mirror of https://github.com/BOINC/boinc.git
MGR: Fix bugs in accessibility code for Notices tab
svn path=/trunk/boinc/; revision=21880
This commit is contained in:
parent
195bbb2814
commit
0951733a49
|
@ -4954,3 +4954,11 @@ David 6 Jul 2010
|
|||
|
||||
html/inc/
|
||||
translation.inc
|
||||
|
||||
Charlie 8 Jul 2010
|
||||
- MGR: Fix bugs in accessibility code for Notices tab.
|
||||
|
||||
clientgui/
|
||||
NoticeListCtrl.cpp, .h
|
||||
mac/
|
||||
MacAccessiblity.cpp
|
||||
|
|
|
@ -60,7 +60,8 @@ wxAccStatus CNoticeListCtrlAccessible::GetName(int childId, wxString* name)
|
|||
|
||||
if (pDoc)
|
||||
{
|
||||
strBuffer = wxString(process_client_message(pDoc->notice(childId-1)->title), wxConvUTF8);
|
||||
strBuffer = wxString(process_client_message(pDoc->notice(childId-1)->title), wxConvUTF8);
|
||||
strBuffer = StripHTMLTags(strBuffer);
|
||||
*name = strBuffer.c_str();
|
||||
}
|
||||
}
|
||||
|
@ -99,25 +100,21 @@ wxAccStatus CNoticeListCtrlAccessible::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.
|
||||
|
@ -181,14 +178,29 @@ wxAccStatus CNoticeListCtrlAccessible::GetDescription(int childId, wxString* des
|
|||
{
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
static wxString strBuffer;
|
||||
wxDateTime dtBuffer;
|
||||
wxString strDescription;
|
||||
wxString strProjectName = wxEmptyString;
|
||||
wxString strArrivalTime = wxEmptyString;
|
||||
|
||||
if (pDoc && (childId != wxACC_SELF))
|
||||
{
|
||||
strBuffer = wxEmptyString;
|
||||
if (pDoc)
|
||||
{
|
||||
strBuffer = wxString(process_client_message(pDoc->notice(childId-1)->description.c_str()), wxConvUTF8);
|
||||
strDescription = wxString(process_client_message(pDoc->notice(childId-1)->description.c_str()), wxConvUTF8);
|
||||
strProjectName = wxString(pDoc->notice(childId-1)->project_name, wxConvUTF8);
|
||||
dtBuffer.Set((time_t)pDoc->notice(childId-1)->arrival_time);
|
||||
strArrivalTime = dtBuffer.Format();
|
||||
if (strProjectName.IsEmpty()) {
|
||||
strBuffer.Printf(_("%s; received on %s"), strDescription.c_str(), strArrivalTime.c_str());
|
||||
} else {
|
||||
strBuffer.Printf(_("%s; received from %s; on %s"), strDescription.c_str(), strProjectName.c_str(), strArrivalTime.c_str());
|
||||
}
|
||||
|
||||
strBuffer = StripHTMLTags(strBuffer);
|
||||
*description = strBuffer.c_str();
|
||||
|
||||
return wxACC_OK;
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +210,20 @@ wxAccStatus CNoticeListCtrlAccessible::GetDescription(int childId, wxString* des
|
|||
}
|
||||
|
||||
|
||||
wxString CNoticeListCtrlAccessible::StripHTMLTags(wxString inBuf) {
|
||||
wxString outBuf = wxEmptyString;
|
||||
wxString tempBuf = inBuf;
|
||||
|
||||
while (!tempBuf.IsEmpty()) {
|
||||
outBuf += tempBuf.BeforeFirst(wxT('<'));
|
||||
tempBuf = tempBuf.AfterFirst(wxT('<'));
|
||||
if (tempBuf.IsEmpty()) break;
|
||||
tempBuf = tempBuf.AfterFirst(wxT('>'));
|
||||
}
|
||||
|
||||
return outBuf;
|
||||
}
|
||||
|
||||
#ifndef __WXMAC__
|
||||
|
||||
// Navigates from fromId to toId/toObject.
|
||||
|
@ -569,14 +595,3 @@ bool CNoticeListCtrl::UpdateUI()
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Return the total height of all the client items.
|
||||
*/
|
||||
|
||||
wxCoord CNoticeListCtrl::GetTotalClientHeight()
|
||||
{
|
||||
return EstimateTotalHeight();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
virtual wxAccStatus GetChildCount(int* childCount);
|
||||
virtual wxAccStatus DoDefaultAction(int childId);
|
||||
virtual wxAccStatus GetDescription(int childId, wxString* description);
|
||||
wxString StripHTMLTags(wxString inBuf);
|
||||
|
||||
#ifndef __WXMAC__
|
||||
virtual wxAccStatus Navigate(wxNavDir navDir, int fromId, int* toId, wxAccessible** toObject);
|
||||
virtual wxAccStatus GetDefaultAction(int childId, wxString* actionName);
|
||||
|
@ -110,7 +112,7 @@ public:
|
|||
|
||||
bool UpdateUI();
|
||||
|
||||
wxCoord GetTotalClientHeight();
|
||||
int GetItemHeight(size_t i) { return (int)OnMeasureItem(i); }
|
||||
|
||||
private:
|
||||
#ifdef __WXMAC__
|
||||
|
|
|
@ -74,6 +74,8 @@ pascal OSStatus BOINCListAccessibilityEventHandler( EventHandlerCallRef inHandle
|
|||
pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef,
|
||||
EventRef inEvent, void* pData);
|
||||
|
||||
pascal OSStatus NoticeListAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef,
|
||||
EventRef inEvent, void* pData);
|
||||
|
||||
static EventTypeSpec myAccessibilityEvents[] = {
|
||||
{ kEventClassAccessibility, kEventAccessibleGetChildAtPoint },
|
||||
|
@ -224,7 +226,7 @@ void CNoticeListCtrlAccessible::SetupMacAccessibilitySupport() {
|
|||
m_listView = (HIViewRef)pCtrl->GetHandle();
|
||||
err = HIViewSetEnabled(m_listView, true);
|
||||
|
||||
err = InstallHIObjectEventHandler((HIObjectRef)m_listView, NewEventHandlerUPP(AttachListAccessibilityEventHandler),
|
||||
err = InstallHIObjectEventHandler((HIObjectRef)m_listView, NewEventHandlerUPP(NoticeListAccessibilityEventHandler),
|
||||
sizeof(myAccessibilityEvents) / sizeof(EventTypeSpec), myAccessibilityEvents,
|
||||
this, &m_plistAccessibilityEventHandlerRef);
|
||||
} else {
|
||||
|
@ -1719,6 +1721,479 @@ pascal OSStatus AttachListAccessibilityEventHandler( EventHandlerCallRef inHandl
|
|||
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 );
|
||||
} 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 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return eventNotHandledErr;
|
||||
} // End switch(eventKind)
|
||||
|
||||
return eventNotHandledErr;
|
||||
}
|
||||
|
||||
|
||||
pascal OSStatus SimpleAccessibilityEventHandler( EventHandlerCallRef inHandlerCallRef,
|
||||
EventRef inEvent, void* pData) {
|
||||
const UInt32 eventClass = GetEventClass(inEvent);
|
||||
|
|
Loading…
Reference in New Issue