From 922a232a7fda42c38d97ea0ff0acf0a9c30e9e22 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Fri, 9 Jul 2010 10:18:48 +0000 Subject: [PATCH] MGR: Fix ProjectListCtrl accessibility code bug, clean up Mac accessibility code svn path=/trunk/boinc/; revision=21886 --- checkin_notes | 10 + clientgui/NoticeListCtrl.cpp | 6 +- clientgui/NoticeListCtrl.h | 2 + clientgui/ProjectListCtrl.cpp | 39 +- clientgui/ProjectListCtrl.h | 6 +- clientgui/mac/MacAccessiblity.cpp | 590 +++++------------------------- 6 files changed, 117 insertions(+), 536 deletions(-) diff --git a/checkin_notes b/checkin_notes index 63e6d8d687..3838e0a7cd 100644 --- a/checkin_notes +++ b/checkin_notes @@ -4981,3 +4981,13 @@ David 8 Jul 2010 client_msgs.cpp win_build/ boinc.sln + +Charlie 9 Jul 2010 + - MGR: Fix accessibility code bug in Attach Wizard's ProjectListCtrl, + consolidate and clean up Mac accessibility code. + + clientgui/ + NoticeListCtrl.cpp, .h + ProjectListCtrl.cpp, .h + mac/ + MacAccessiblity.cpp diff --git a/clientgui/NoticeListCtrl.cpp b/clientgui/NoticeListCtrl.cpp index dffd95f435..272fb01540 100644 --- a/clientgui/NoticeListCtrl.cpp +++ b/clientgui/NoticeListCtrl.cpp @@ -28,8 +28,12 @@ ////@begin XPM images ////@end XPM images +#if wxUSE_ACCESSIBILITY || defined(__WXMAC__) + #ifdef __WXMAC__ +IMPLEMENT_CLASS( CNoticeListCtrlAccessible, wxObject ) + CNoticeListCtrlAccessible::CNoticeListCtrlAccessible(wxWindow* win) { mp_win = win; SetupMacAccessibilitySupport(); @@ -42,8 +46,6 @@ CNoticeListCtrlAccessible::~CNoticeListCtrlAccessible() { #endif -#if wxUSE_ACCESSIBILITY || defined(__WXMAC__) - // Gets the name of the specified object. wxAccStatus CNoticeListCtrlAccessible::GetName(int childId, wxString* name) { diff --git a/clientgui/NoticeListCtrl.h b/clientgui/NoticeListCtrl.h index e095c69b74..bb57920ef3 100644 --- a/clientgui/NoticeListCtrl.h +++ b/clientgui/NoticeListCtrl.h @@ -46,6 +46,8 @@ public: #ifndef __WXMAC__ CNoticeListCtrlAccessible(wxWindow* win): wxWindowAccessible(win) {} #else + DECLARE_CLASS( CNoticeListCtrlAccessible ) + CNoticeListCtrlAccessible(wxWindow* win); virtual ~CNoticeListCtrlAccessible(); #endif diff --git a/clientgui/ProjectListCtrl.cpp b/clientgui/ProjectListCtrl.cpp index f2421e42f4..1706d98374 100644 --- a/clientgui/ProjectListCtrl.cpp +++ b/clientgui/ProjectListCtrl.cpp @@ -32,8 +32,12 @@ ////@end XPM images +#if wxUSE_ACCESSIBILITY || defined(__WXMAC__) + #ifdef __WXMAC__ +IMPLEMENT_CLASS( CProjectListCtrlAccessible, wxObject ) + CProjectListCtrlAccessible::CProjectListCtrlAccessible(wxWindow* win) { mp_win = win; SetupMacAccessibilitySupport(); @@ -46,8 +50,6 @@ CProjectListCtrlAccessible::~CProjectListCtrlAccessible() { #endif -#if wxUSE_ACCESSIBILITY || defined(__WXMAC__) - // Gets the name of the specified object. wxAccStatus CProjectListCtrlAccessible::GetName(int childId, wxString* name) { @@ -98,25 +100,21 @@ wxAccStatus CProjectListCtrlAccessible::GetLocation(wxRect& rect, int elementId) { // List item wxSize cCtrlSize = pCtrl->GetClientSize(); - int iItemWidth = cCtrlSize.GetWidth(); - int iItemHeight = pCtrl->GetTotalClientHeight() / (int)pCtrl->GetItemCount(); // Set the initial control postition to the absolute coords of the upper // left hand position of the control rect.SetPosition(pCtrl->GetScreenPosition()); - rect.width = iItemWidth - 1; - rect.height = iItemHeight - 1; + rect.width = cCtrlSize.GetWidth() - 1; + rect.height = pCtrl->GetItemHeight(elementId - 1) - 1; - if (1 == elementId) - { - // First child - } - else - { - // Other children - rect.SetTop(rect.GetTop() + ((elementId - 1) * iItemHeight) + 1); - rect.height -= 1; + // Items can have different heights + int firstVisibleItem = (int)pCtrl->GetFirstVisibleLine(); + int yOffset = 0; + for (int i=firstVisibleItem; i<(elementId - 1); ++i) { + yOffset += pCtrl->GetItemHeight((size_t)i); } + rect.SetTop(rect.GetTop() + yOffset); + rect.height -= 1; return wxACC_OK; } // Let the framework handle the other cases. @@ -606,14 +604,3 @@ CProjectListItem* CProjectListCtrl::GetItem( { return m_Items[iIndex]; } - - -/*! - * Return the total height of all the client items. - */ - -wxCoord CProjectListCtrl::GetTotalClientHeight() -{ - return EstimateTotalHeight(); -} - diff --git a/clientgui/ProjectListCtrl.h b/clientgui/ProjectListCtrl.h index f38ebdf2bb..36e902c479 100644 --- a/clientgui/ProjectListCtrl.h +++ b/clientgui/ProjectListCtrl.h @@ -94,6 +94,8 @@ class CProjectListCtrlAccessible: public wxWindowAccessible public: #ifdef __WXMAC__ + DECLARE_CLASS( CProjectListCtrlAccessible ) + CProjectListCtrlAccessible(wxWindow* win); virtual ~CProjectListCtrlAccessible(); #else @@ -162,6 +164,8 @@ public: virtual wxString OnGetItem(size_t i) const; + int GetItemHeight(size_t i) { return (int)OnMeasureItem(i); } + /// Methods bool Append( wxString strURL, @@ -178,8 +182,6 @@ public: int iIndex ); - wxCoord GetTotalClientHeight(); - private: std::vector m_Items; diff --git a/clientgui/mac/MacAccessiblity.cpp b/clientgui/mac/MacAccessiblity.cpp index dfaf88730e..0a2ddbdf99 100755 --- a/clientgui/mac/MacAccessiblity.cpp +++ b/clientgui/mac/MacAccessiblity.cpp @@ -71,10 +71,7 @@ void AccessibilityIgnoreAllChildren(HIViewRef parent, int recursionLevel) { pascal OSStatus BOINCListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* pData); -pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, - EventRef inEvent, void* pData); - -pascal OSStatus NoticeListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, +pascal OSStatus HTMLListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* pData); static EventTypeSpec myAccessibilityEvents[] = { @@ -198,7 +195,7 @@ void CProjectListCtrlAccessible::SetupMacAccessibilitySupport() { m_listView = (HIViewRef)pCtrl->GetHandle(); err = HIViewSetEnabled(m_listView, true); - err = InstallHIObjectEventHandler((HIObjectRef)m_listView, NewEventHandlerUPP(AttachListAccessibilityEventHandler), + err = InstallHIObjectEventHandler((HIObjectRef)m_listView, NewEventHandlerUPP(HTMLListAccessibilityEventHandler), sizeof(myAccessibilityEvents) / sizeof(EventTypeSpec), myAccessibilityEvents, this, &m_plistAccessibilityEventHandlerRef); } else { @@ -226,7 +223,7 @@ void CNoticeListCtrlAccessible::SetupMacAccessibilitySupport() { m_listView = (HIViewRef)pCtrl->GetHandle(); err = HIViewSetEnabled(m_listView, true); - err = InstallHIObjectEventHandler((HIObjectRef)m_listView, NewEventHandlerUPP(NoticeListAccessibilityEventHandler), + err = InstallHIObjectEventHandler((HIObjectRef)m_listView, NewEventHandlerUPP(HTMLListAccessibilityEventHandler), sizeof(myAccessibilityEvents) / sizeof(EventTypeSpec), myAccessibilityEvents, this, &m_plistAccessibilityEventHandlerRef); } else { @@ -1250,22 +1247,33 @@ pascal OSStatus BOINCListAccessibilityEventHandler( EventHandlerCallRef inHandle } -pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, +pascal OSStatus HTMLListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* pData) { const UInt32 eventClass = GetEventClass(inEvent); const UInt32 eventKind = GetEventKind(inEvent); + CProjectListCtrlAccessible* pProjectListCtrlAccessible = NULL; + CProjectListCtrl* pProjectListCtrl = NULL; + CNoticeListCtrlAccessible* pNoticeListCtrlAccessible = NULL; + CNoticeListCtrl* pNoticeListCtrl = NULL; OSStatus err; - CProjectListCtrlAccessible* pAccessible = (CProjectListCtrlAccessible*)pData; - if (pAccessible == NULL) { - return eventNotHandledErr; + pProjectListCtrlAccessible = wxDynamicCast(pData, CProjectListCtrlAccessible); + if (pProjectListCtrlAccessible != NULL) { + pProjectListCtrl = wxDynamicCast(pProjectListCtrlAccessible->GetWindow(), CProjectListCtrl); + if (pProjectListCtrl == NULL) { + return eventNotHandledErr; + } + } else { + pNoticeListCtrlAccessible = wxDynamicCast(pData, CNoticeListCtrlAccessible); + if (pNoticeListCtrlAccessible == NULL) { + return eventNotHandledErr; + } + pNoticeListCtrl = wxDynamicCast(pNoticeListCtrlAccessible->GetWindow(), CNoticeListCtrl); + if (pNoticeListCtrl == NULL) { + return eventNotHandledErr; + } } - CProjectListCtrl* pCtrl = wxDynamicCast(pAccessible->GetWindow(), CProjectListCtrl); - if (pCtrl == NULL) { - return eventNotHandledErr; - } - if (eventClass != kEventClassAccessibility) { return eventNotHandledErr; } @@ -1303,9 +1311,13 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl if (err) return err; wxPoint p((int)where.x, (int)where.y); - pCtrl->ScreenToClient(&p.x, &p.y); - - err = pAccessible->HitTest(p, &hitRow, NULL); + if (pProjectListCtrlAccessible) { + pProjectListCtrl->ScreenToClient(&p.x, &p.y); + err = pProjectListCtrlAccessible->HitTest(p, &hitRow, NULL); + } else { + pNoticeListCtrl->ScreenToClient(&p.x, &p.y); + err = pNoticeListCtrlAccessible->HitTest(p, &hitRow, NULL); + } if (err) { return eventNotHandledErr; @@ -1406,7 +1418,11 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl wxRect r; HISize theSize; - err = pAccessible->GetLocation(r, row); + if (pProjectListCtrlAccessible) { + err = pProjectListCtrlAccessible->GetLocation(r, row); + } else { + err = pNoticeListCtrlAccessible->GetLocation(r, row); + } if (err) { return eventNotHandledErr; } @@ -1420,20 +1436,18 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl } else if ( CFStringCompare( attribute, kAXPositionAttribute, 0 ) == kCFCompareEqualTo ) { wxRect r; HIPoint pt; - int x, y; - err = pAccessible->GetLocation(r, row); + if (pProjectListCtrlAccessible) { + err = pProjectListCtrlAccessible->GetLocation(r, row); + } else { + err = pNoticeListCtrlAccessible->GetLocation(r, row); + } if (err) { return eventNotHandledErr; } - x = r.x; - y = r.y; - - // Now convert to global coordinates - pCtrl->ClientToScreen(&x, &y); - pt.x = x; - pt.y = y; + pt.x = r.x; + pt.y = r.y; SetEventParameter(inEvent, kEventParamAccessibleAttributeValue, typeHIPoint, sizeof(HIPoint), &pt); return noErr; @@ -1449,7 +1463,11 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl AXUIElementRef child; int i, n; - err = pAccessible->GetChildCount(&n); + if (pProjectListCtrlAccessible) { + err = pProjectListCtrlAccessible->GetChildCount(&n); + } else { + err = pNoticeListCtrlAccessible->GetChildCount(&n); + } children = CFArrayCreateMutable( kCFAllocatorDefault, n, &kCFTypeArrayCallBacks ); for ( i = 0; i < n; i++ ) { @@ -1486,7 +1504,11 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl AXUIElementRef parent; HIViewRef parentView; - parentView = HIViewGetSuperview(pAccessible->m_listView); + if (pProjectListCtrlAccessible) { + parentView = HIViewGetSuperview(pProjectListCtrlAccessible->m_listView); + } else { + parentView = HIViewGetSuperview(pNoticeListCtrlAccessible->m_listView); + } parent = AXUIElementCreateWithHIObjectAndIdentifier((HIObjectRef)parentView, 0); if (parent == NULL) { return eventNotHandledErr; @@ -1505,19 +1527,34 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl if ( CFStringCompare( attribute, kAXDescriptionAttribute, 0 ) == kCFCompareEqualTo ) { wxString str, buf; int n; + Boolean selected = false; - err = pAccessible->GetChildCount(&n); + if (pProjectListCtrlAccessible) { + err = pProjectListCtrlAccessible->GetChildCount(&n); + } else { + err = pNoticeListCtrlAccessible->GetChildCount(&n); + } if (err) { return eventNotHandledErr; } - if (pCtrl->IsSelected(row - 1)) { + if (pProjectListCtrl) { + selected = pProjectListCtrl->IsSelected(row - 1); + } else { + selected = pNoticeListCtrl->IsSelected(row - 1); + } + + if (selected) { str.Printf(_("selected row %d of %d; "), row, n); } else { str.Printf(_("row %d of %d; "), row, n); } - err = pAccessible->GetDescription(row, &buf); + if (pProjectListCtrlAccessible) { + err = pProjectListCtrlAccessible->GetDescription(row, &buf); + } else { + err = pNoticeListCtrlAccessible->GetDescription(row, &buf); + } if (err) { return eventNotHandledErr; } @@ -1532,7 +1569,11 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl AXUIElementRef parent; HIViewRef parentView; - parentView = pAccessible->m_listView; + if (pProjectListCtrlAccessible) { + parentView = pProjectListCtrlAccessible->m_listView; + } else { + parentView = pNoticeListCtrlAccessible->m_listView; + } parent = AXUIElementCreateWithHIObjectAndIdentifier((HIObjectRef)parentView, 0); if (parent == NULL) { return eventNotHandledErr; @@ -1600,7 +1641,11 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl wxString str; wxListItem headerItem; - pAccessible->GetName(row, &str); + if (pProjectListCtrlAccessible) { + pProjectListCtrlAccessible->GetName(row, &str); + } else { + pNoticeListCtrlAccessible->GetName(row, &str); + } CFStringRef title = CFStringCreateWithCString(NULL, str.char_str(), kCFStringEncodingUTF8); SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( title ), &title ); @@ -1705,479 +1750,11 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl if ( CFStringCompare( action, kAXPressAction, 0 ) != kCFCompareEqualTo ) { return eventNotHandledErr; } - err = pAccessible->DoDefaultAction(inIdentifier); - if (err) { - return eventNotHandledErr; - } - - return noErr; - } - break; - - default: - return eventNotHandledErr; - } // End switch(eventKind) - - return eventNotHandledErr; -} - - -pascal OSStatus NoticeListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, - EventRef inEvent, void* pData) { - const UInt32 eventClass = GetEventClass(inEvent); - const UInt32 eventKind = GetEventKind(inEvent); - OSStatus err; - - CProjectListCtrlAccessible* pAccessible = (CProjectListCtrlAccessible*)pData; - if (pAccessible == NULL) { - return eventNotHandledErr; - } - - CNoticeListCtrl* pCtrl = wxDynamicCast(pAccessible->GetWindow(), CNoticeListCtrl); - if (pCtrl == NULL) { - return eventNotHandledErr; - } - - if (eventClass != kEventClassAccessibility) { - return eventNotHandledErr; - } - - AXUIElementRef element; - UInt64 inIdentifier = 0; - UInt64 outIdentifier = 0; - SInt32 row = 0; - HIObjectRef obj = NULL; - - err = GetEventParameter (inEvent, kEventParamAccessibleObject, - typeCFTypeRef, NULL, sizeof(typeCFTypeRef), NULL, &element); - if (err) return err; - - AXUIElementGetIdentifier( element, &inIdentifier ); - obj = AXUIElementGetHIObject(element); - - row = inIdentifier; - - switch (eventKind) { -#pragma mark kEventAccessibleGetChildAtPoint - case kEventAccessibleGetChildAtPoint: - { - CFTypeRef child = NULL; - HIPoint where; - int hitRow; - - // Only the whole view can be tested since the parts don't have sub-parts. - if (inIdentifier != 0) { - return noErr; - } - - err = GetEventParameter (inEvent, kEventParamMouseLocation, - typeHIPoint, NULL, sizeof(HIPoint), NULL, &where); - if (err) return err; - - wxPoint p((int)where.x, (int)where.y); - pCtrl->ScreenToClient(&p.x, &p.y); - - err = pAccessible->HitTest(p, &hitRow, NULL); - - if (err) { - return eventNotHandledErr; - } - - if (hitRow >= 0) { - outIdentifier = hitRow + 1; - child = AXUIElementCreateWithHIObjectAndIdentifier(obj, outIdentifier ); - if (child == NULL) { - return eventNotHandledErr; - } - - err = SetEventParameter (inEvent, kEventParamAccessibleChild, typeCFTypeRef, - sizeof(typeCFTypeRef), &child); - if (err) { - return eventNotHandledErr; - } - } - - return noErr; - } - break; - -#pragma mark kEventAccessibleGetFocusedChild - case kEventAccessibleGetFocusedChild: - return noErr; - break; - -#pragma mark kEventAccessibleGetAllAttributeNames - case kEventAccessibleGetAllAttributeNames: - { - CFMutableArrayRef namesArray; - - err = GetEventParameter (inEvent, kEventParamAccessibleAttributeNames, - typeCFMutableArrayRef, NULL, sizeof(typeCFMutableArrayRef), NULL, &namesArray); - if (err) - return err; - - CallNextEventHandler( inHandlerCallRef, inEvent ); - - if ( inIdentifier == 0 ) - { - // Identifier 0 means "the whole view". - // Let accessibility know that this view has children and can - // return a list of them. - CFArrayAppendValue( namesArray, kAXChildrenAttribute ); + if (pProjectListCtrlAccessible) { + err = pProjectListCtrlAccessible->DoDefaultAction(inIdentifier); } else { - // Let accessibility know that this view's children can return description, - // size, position, parent window, top level element and isFocused attributes. - CFArrayAppendValue( namesArray, kAXWindowAttribute ); - CFArrayAppendValue( namesArray, kAXTopLevelUIElementAttribute ); - CFArrayAppendValue( namesArray, kAXDescriptionAttribute ); - CFArrayAppendValue( namesArray, kAXSizeAttribute ); - CFArrayAppendValue( namesArray, kAXPositionAttribute ); - CFArrayAppendValue( namesArray, kAXTitleAttribute ); - CFArrayAppendValue( namesArray, kAXEnabledAttribute ); + err = pNoticeListCtrlAccessible->DoDefaultAction(inIdentifier); } - - CFArrayAppendValue( namesArray, kAXFocusedAttribute ); - CFArrayAppendValue( namesArray, kAXRoleAttribute ); - CFArrayAppendValue( namesArray, kAXRoleDescriptionAttribute ); - CFArrayAppendValue( namesArray, kAXParentAttribute ); - - return noErr; - } - break; - -#pragma mark kEventAccessibleGetAllParameterizedAttributeNames - case kEventAccessibleGetAllParameterizedAttributeNames: - { - CFMutableArrayRef namesArray; - - err = GetEventParameter (inEvent, kEventParamAccessibleAttributeNames, - typeCFMutableArrayRef, NULL, sizeof(typeCFMutableArrayRef), NULL, &namesArray); - if (err) return err; - - return noErr; - } - break; - -#pragma mark kEventAccessibleGetNamedAttribute - case kEventAccessibleGetNamedAttribute: - { - CFStringRef attribute; - - err = GetEventParameter (inEvent, kEventParamAccessibleAttributeName, - typeCFStringRef, NULL, sizeof(typeCFStringRef), NULL, &attribute); - if (err) return err; - - if ( CFStringCompare( attribute, kAXFocusedAttribute, 0 ) == kCFCompareEqualTo ) { - // Return whether or not this part is focused. -//TODO: Add kAXFocusedAttribute support? - Boolean focused = false; - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeBoolean, sizeof( focused ), &focused ); - return noErr; - } else if ( CFStringCompare( attribute, kAXSizeAttribute, 0 ) == kCFCompareEqualTo ) { - wxRect r; - HISize theSize; - - err = pAccessible->GetLocation(r, row); - if (err) { - return eventNotHandledErr; - } - - theSize.width = r.width; - theSize.height = r.height; - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeHISize, sizeof( HISize ), &theSize ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXPositionAttribute, 0 ) == kCFCompareEqualTo ) { - wxRect r; - HIPoint pt; - int x, y; - - err = pAccessible->GetLocation(r, row); - if (err) { - return eventNotHandledErr; - } - - x = r.x; - y = r.y; - - // Now convert to global coordinates -// pCtrl->ClientToScreen(&x, &y); - pt.x = x; - pt.y = y; - - SetEventParameter(inEvent, kEventParamAccessibleAttributeValue, typeHIPoint, sizeof(HIPoint), &pt); - return noErr; - } - - if ( inIdentifier == 0 ) { - // String compare the incoming attribute name and return the appropriate accessibility - // information as an event parameter. - - if ( CFStringCompare( attribute, kAXChildrenAttribute, 0 ) == kCFCompareEqualTo ) { - // Create and return an array of AXUIElements describing the children of this view. - CFMutableArrayRef children; - AXUIElementRef child; - int i, n; - - err = pAccessible->GetChildCount(&n); - children = CFArrayCreateMutable( kCFAllocatorDefault, n, &kCFTypeArrayCallBacks ); - - for ( i = 0; i < n; i++ ) { - outIdentifier = i+1; - child = AXUIElementCreateWithHIObjectAndIdentifier( obj, outIdentifier ); - CFArrayAppendValue( children, child ); - CFRelease( child ); - } - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( children ), &children ); - CFRelease( children ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXRoleAttribute, 0 ) == kCFCompareEqualTo ) { - // Return a string indicating the role of this view. Using the table role doesn't work. - CFStringRef role = kAXListRole; - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( role ), &role ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXRoleDescriptionAttribute, 0 ) == kCFCompareEqualTo ) { - // Return a string indicating the role of this part. -//TODO: specify whether projects or account managers - wxString str; - - str = _("list of projects or account managers"); - CFStringRef roleDesc = CFStringCreateWithCString(NULL, str.char_str(), kCFStringEncodingUTF8); - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( roleDesc ), &roleDesc ); - CFRelease( roleDesc ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXParentAttribute, 0 ) == kCFCompareEqualTo ) { - AXUIElementRef parent; - HIViewRef parentView; - - parentView = HIViewGetSuperview(pAccessible->m_listView); - parent = AXUIElementCreateWithHIObjectAndIdentifier((HIObjectRef)parentView, 0); - if (parent == NULL) { - return eventNotHandledErr; - } - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( parent ), &parent ); - CFRelease( parent ); - return noErr; - - } else { - return CallNextEventHandler( inHandlerCallRef, inEvent ); - - } - - } else { // End if ( inIdentifier == 0 ) - - if ( CFStringCompare( attribute, kAXDescriptionAttribute, 0 ) == kCFCompareEqualTo ) { - wxString str, buf; - int n; - - err = pAccessible->GetChildCount(&n); - if (err) { - return eventNotHandledErr; - } - - if (pCtrl->IsSelected(row - 1)) { - str.Printf(_("selected row %d of %d; "), row, n); - } else { - str.Printf(_("row %d of %d; "), row, n); - } - - err = pAccessible->GetDescription(row, &buf); - if (err) { - return eventNotHandledErr; - } - str += buf; - - CFStringRef description = CFStringCreateWithCString(NULL, str.char_str(), kCFStringEncodingUTF8); - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( description ), &description ); - CFRelease( description ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXParentAttribute, 0 ) == kCFCompareEqualTo ) { - AXUIElementRef parent; - HIViewRef parentView; - - parentView = pAccessible->m_listView; - parent = AXUIElementCreateWithHIObjectAndIdentifier((HIObjectRef)parentView, 0); - if (parent == NULL) { - return eventNotHandledErr; - } - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( parent ), &parent ); - CFRelease( parent ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXSubroleAttribute, 0 ) == kCFCompareEqualTo ) { - return eventNotHandledErr; - - } else if ( CFStringCompare( attribute, kAXRoleAttribute, 0 ) == kCFCompareEqualTo ) { - // Return a string indicating the role of this part. The parts of the view behave like - // buttons, so use that system role. - - CFStringRef role = kAXStaticTextRole; // kAXRowRole; - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( role ), &role ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXRoleDescriptionAttribute, 0 ) == kCFCompareEqualTo ) { - // Return a string describing the role of this part. Use the system description. - CFStringRef roleDesc = HICopyAccessibilityRoleDescription( kAXRowRole, NULL ); - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( roleDesc ), &roleDesc ); - CFRelease( roleDesc ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXWindowAttribute, 0 ) == kCFCompareEqualTo - || CFStringCompare( attribute, kAXTopLevelUIElementAttribute, 0 ) == kCFCompareEqualTo ) { - // Return the window or top level ui element for this part. They are both the same so re-use the code. - AXUIElementRef windOrTopUI; - - WindowRef win = GetControlOwner((HIViewRef)obj); - if (win == NULL) { - return eventNotHandledErr; - } - - windOrTopUI = AXUIElementCreateWithHIObjectAndIdentifier( (HIObjectRef)win, 0 ); - if (windOrTopUI == NULL) { - return eventNotHandledErr; - } - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( windOrTopUI ), &windOrTopUI ); - CFRelease( windOrTopUI ); - return noErr; - - } else if ( CFStringCompare( attribute, kAXEnabledAttribute, 0 ) == kCFCompareEqualTo ) { - Boolean enabled = true; - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeBoolean, sizeof( enabled ), &enabled ); - return noErr; - -//TODO: Add kAXFocusedAttribute support? -#if 0 - } else if ( CFStringCompare( attribute, kAXFocusedAttribute, 0 ) == kCFCompareEqualTo ) { - // Return whether or not this part is focused. - Boolean focused = false; - - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeBoolean, sizeof( focused ), &focused ); - return noErr; -#endif - - } else if ( CFStringCompare( attribute, kAXTitleAttribute, 0 ) == kCFCompareEqualTo ) { - // Return the item's text - wxString str; - wxListItem headerItem; - - pAccessible->GetName(row, &str); - - CFStringRef title = CFStringCreateWithCString(NULL, str.char_str(), kCFStringEncodingUTF8); - SetEventParameter( inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( title ), &title ); - CFRelease( title ); - return noErr; - - } else { - return eventNotHandledErr; - } - - } // End if ( inIdentifier != 0 ) - break; - } // End case kEventAccessibleGetNamedAttribute: - -#pragma mark kEventAccessibleIsNamedAttributeSettable - case kEventAccessibleIsNamedAttributeSettable: - { - CFStringRef attribute; - Boolean isSettable = false; - - err = GetEventParameter (inEvent, kEventParamAccessibleAttributeName, - typeCFStringRef, NULL, sizeof(typeCFStringRef), NULL, &attribute); - if (err) return err; - - // The focused attribute is the only settable attribute for this view, - // and it can only be set on part (or subelements), not the whole view. - if (inIdentifier != 0) - { - if ( CFStringCompare( attribute, kAXFocusedAttribute, 0 ) == kCFCompareEqualTo ) - { - isSettable = true; - } - } - SetEventParameter( inEvent, kEventParamAccessibleAttributeSettable, typeBoolean, sizeof( Boolean ), &isSettable ); - return noErr; - } - break; - -#pragma mark kEventAccessibleSetNamedAttribute - case kEventAccessibleSetNamedAttribute: - { - return eventNotHandledErr; - } - break; - -#pragma mark kEventAccessibleGetAllActionNames - case kEventAccessibleGetAllActionNames: - { - CFMutableArrayRef array; - - err = GetEventParameter (inEvent, kEventParamAccessibleActionNames, - typeCFMutableArrayRef, NULL, sizeof(typeCFMutableArrayRef), NULL, &array); - if (err) return err; - - if (inIdentifier != 0) { - CFArrayAppendValue( array, kAXPressAction ); - } - return noErr; - } - break; - -#pragma mark kEventAccessibleGetNamedActionDescription - case kEventAccessibleGetNamedActionDescription: - { - CFStringRef action; - CFMutableStringRef desc; - CFStringRef selfDesc = NULL; - - if (inIdentifier == 0) { - return eventNotHandledErr; - } - - err = GetEventParameter (inEvent, kEventParamAccessibleActionName, - typeCFStringRef, NULL, sizeof(typeCFStringRef), NULL, &action); - if (err) return err; - - err = GetEventParameter (inEvent, kEventParamAccessibleActionDescription, - typeCFMutableStringRef, NULL, sizeof(typeCFMutableStringRef), NULL, &desc); - if (err) return err; - - selfDesc = HICopyAccessibilityActionDescription( action ); - - CFStringReplaceAll( desc, selfDesc ); - CFRelease( selfDesc ); - return noErr; - } - break; - -#pragma mark kEventAccessiblePerformNamedAction - case kEventAccessiblePerformNamedAction: - { - CFStringRef action; - - if (inIdentifier == 0) { - return eventNotHandledErr; - } - - err = GetEventParameter (inEvent, kEventParamAccessibleActionName, - typeCFStringRef, NULL, sizeof(typeCFStringRef), NULL, &action); - if (err) return err; - - if ( CFStringCompare( action, kAXPressAction, 0 ) != kCFCompareEqualTo ) { - return eventNotHandledErr; - } - err = pAccessible->DoDefaultAction(inIdentifier); if (err) { return eventNotHandledErr; } @@ -2194,6 +1771,7 @@ pascal OSStatus NoticeListAccessibilityEventHandler( EventHandlerCallRef inHandl } + pascal OSStatus SimpleAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* pData) { const UInt32 eventClass = GetEventClass(inEvent);