office-gobmx/winaccessibility/source/service/AccObject.cxx
Michael Stahl 3b86569fcb winaccessibility: replace CoCreateInstance with direct instantiation
This is an alternative (to 732ec36edf)
solution to the "CoCreateInstance does not work" problem:
replace all CoCreateInstance calls with equivalent calls to create
the components directly.

Since the only reason why this COM stuff needs to be registered
at all is that AccObject uses CoCreateInstance() to create its
COM objects, another possible solution appears to be to simply link
the libraries and instantiate the COM objects directly, without COM.

The only difference appears to be that CoCreateInstance would
automatically add proxy objects in case the COM objects reside in a
single-threaded appartment; not sure if that is relevant here.

Change-Id: I8ffb8af501f6084f3145fa4d4f53366a070e1691
Reviewed-on: https://gerrit.libreoffice.org/6792
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
2013-11-25 03:21:30 -06:00

1193 lines
31 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/XAccessibleValue.hpp>
#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
#include <com/sun/star/accessibility/XAccessibleText.hpp>
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#include <memory.h>
#include <algorithm>
#include <assert.h>
#include "AccObject.hxx"
#include "AccEventListener.hxx"
#include "UAccCOM_i.c"
#include "AccResource.hxx"
#include "act.hxx"
using namespace std;
using namespace com::sun::star::uno;
using namespace com::sun::star::accessibility;
using namespace com::sun::star::accessibility::AccessibleRole;
using namespace com::sun::star::accessibility::AccessibleStateType;
//Role mapping table,left side is UNO role, right side is MSAA role
const short ROLE_TABLE[][2] =
{
{UNKNOWN, IA2_ROLE_UNKNOWN},
{ALERT , ROLE_SYSTEM_DIALOG},
{COLUMN_HEADER , ROLE_SYSTEM_COLUMNHEADER},
//{CANVAS , ROLE_SYSTEM_CLIENT},
{CANVAS , IA2_ROLE_CANVAS},
{CHECK_BOX , ROLE_SYSTEM_CHECKBUTTON},
{CHECK_MENU_ITEM , IA2_ROLE_CHECK_MENU_ITEM},
{COLOR_CHOOSER, IA2_ROLE_COLOR_CHOOSER},
{COMBO_BOX , ROLE_SYSTEM_COMBOBOX},
{DATE_EDITOR , IA2_ROLE_DATE_EDITOR},
{DESKTOP_ICON , IA2_ROLE_DESKTOP_ICON},
{DESKTOP_PANE, IA2_ROLE_DESKTOP_PANE},
{DIRECTORY_PANE, IA2_ROLE_DIRECTORY_PANE},
{DIALOG, ROLE_SYSTEM_DIALOG},
{DOCUMENT, ROLE_SYSTEM_DOCUMENT},
{EMBEDDED_OBJECT , IA2_ROLE_EMBEDDED_OBJECT },
{END_NOTE , IA2_ROLE_ENDNOTE },
{FILE_CHOOSER , IA2_ROLE_FILE_CHOOSER },
{FILLER, ROLE_SYSTEM_WHITESPACE},
{FONT_CHOOSER, IA2_ROLE_FONT_CHOOSER},
{FOOTER, IA2_ROLE_FOOTER},
{FOOTNOTE, IA2_ROLE_FOOTNOTE},
//{FRAME, IA2_ROLE_FRAME},
{FRAME, ROLE_SYSTEM_DIALOG},
{GLASS_PANE , IA2_ROLE_GLASS_PANE},
{GRAPHIC , ROLE_SYSTEM_GRAPHIC},
{GROUP_BOX, ROLE_SYSTEM_GROUPING},
{HEADER , IA2_ROLE_HEADER},
{HEADING , IA2_ROLE_HEADING},
{HYPER_LINK , ROLE_SYSTEM_TEXT},
{ICON , IA2_ROLE_ICON},
{INTERNAL_FRAME, IA2_ROLE_INTERNAL_FRAME},
{LABEL, ROLE_SYSTEM_STATICTEXT},
{LAYERED_PANE , IA2_ROLE_LAYERED_PANE},
{LIST , ROLE_SYSTEM_LIST},
{LIST_ITEM , ROLE_SYSTEM_LISTITEM},
//{MENU , ROLE_SYSTEM_MENUPOPUP},
{MENU, ROLE_SYSTEM_MENUITEM},
{MENU_BAR, ROLE_SYSTEM_MENUBAR},
{MENU_ITEM, ROLE_SYSTEM_MENUITEM},
{OPTION_PANE , IA2_ROLE_OPTION_PANE},
{PAGE_TAB, ROLE_SYSTEM_PAGETAB},
{PAGE_TAB_LIST, ROLE_SYSTEM_PAGETABLIST},
{PANEL, IA2_ROLE_OPTION_PANE},
{PARAGRAPH, IA2_ROLE_PARAGRAPH},
{PASSWORD_TEXT, ROLE_SYSTEM_TEXT},
{POPUP_MENU, ROLE_SYSTEM_MENUPOPUP},
{PUSH_BUTTON, ROLE_SYSTEM_PUSHBUTTON},
{PROGRESS_BAR, ROLE_SYSTEM_PROGRESSBAR},
{RADIO_BUTTON, ROLE_SYSTEM_RADIOBUTTON},
{RADIO_MENU_ITEM, IA2_ROLE_RADIO_MENU_ITEM},
{ROW_HEADER , ROLE_SYSTEM_ROWHEADER},
{ROOT_PANE, IA2_ROLE_ROOT_PANE},
{SCROLL_BAR , ROLE_SYSTEM_SCROLLBAR},
{SCROLL_PANE , IA2_ROLE_SCROLL_PANE},
{SHAPE, IA2_ROLE_SHAPE},
{SEPARATOR , ROLE_SYSTEM_SEPARATOR},
{SLIDER , ROLE_SYSTEM_SLIDER},
{SPIN_BOX , ROLE_SYSTEM_SPINBUTTON},
{SPLIT_PANE, IA2_ROLE_SPLIT_PANE},
{STATUS_BAR, ROLE_SYSTEM_STATUSBAR},
{TABLE, ROLE_SYSTEM_TABLE},
{TABLE_CELL , ROLE_SYSTEM_CELL},
{TEXT, ROLE_SYSTEM_TEXT},
{TEXT_FRAME , IA2_ROLE_TEXT_FRAME},
//for change toggle button to push button for jaws
{TOGGLE_BUTTON, ROLE_SYSTEM_PUSHBUTTON},
{TOOL_BAR, ROLE_SYSTEM_TOOLBAR},
{TOOL_TIP, ROLE_SYSTEM_TOOLTIP},
{TREE , ROLE_SYSTEM_OUTLINE},
{VIEW_PORT , IA2_ROLE_VIEW_PORT},
{WINDOW, ROLE_SYSTEM_WINDOW},
{BUTTON_DROPDOWN, ROLE_SYSTEM_BUTTONDROPDOWN},
{BUTTON_MENU, ROLE_SYSTEM_BUTTONMENU},
{CAPTION, IA2_ROLE_CAPTION},
{CHART, IA2_ROLE_SHAPE},
{EDIT_BAR, IA2_ROLE_EDITBAR},
{FORM, IA2_ROLE_FORM},
{IMAGE_MAP , IA2_ROLE_IMAGE_MAP},
{NOTE, IA2_ROLE_NOTE},
{PAGE, IA2_ROLE_PAGE},
{RULER , IA2_ROLE_RULER},
{SECTION, IA2_ROLE_SECTION},
{TREE_ITEM , ROLE_SYSTEM_OUTLINEITEM},
{TREE_TABLE, ROLE_SYSTEM_OUTLINE}
};
/**
* Constructor.
* @param pXAcc Uno XAccessible interface of control.
* @param Agent The agent kept in all listeners,it's the sole interface by which
* listener communicate with windows manager.
* @param listener listener that registers in UNO system.
* @return.
*/
AccObject::AccObject(XAccessible* pAcc, AccObjectManagerAgent* pAgent,
AccEventListener* listener) :
m_pIMAcc (NULL),
m_resID (NULL),
m_pParantID (NULL),
m_pParentObj(NULL),
m_accListener (listener),
m_bShouldDestroy(sal_False),
m_xAccRef( pAcc )
{
sal_Bool bRet = ImplInitializeCreateObj();
m_xAccContextRef = m_xAccRef->getAccessibleContext();
m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
m_accRole = m_xAccContextRef -> getAccessibleRole();
if( m_pIMAcc )
{
m_pIMAcc->SetXAccessible(reinterpret_cast<hyper>(m_xAccRef.get()));
m_pIMAcc->Put_XAccAgent(reinterpret_cast<hyper>(pAgent));
m_pIMAcc->SetDefaultAction(reinterpret_cast<hyper>(m_xAccActionRef.get()));
}
}
/**
* Destructor.
* @param
* @return
*/
AccObject::~AccObject()
{
m_pIMAcc = NULL;
m_xAccRef = NULL;
m_xAccActionRef = NULL;
m_xAccContextRef = NULL;
}
/**
* Insert a child element.
* @param pChild Child element that should be inserted into child list.
* @param pos Insert postion.
* @return
*/
void AccObject::InsertChild( AccObject* pChild,short pos )
{
std::vector<AccObject*>::iterator iter;
iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
if(iter!=m_childrenList.end())
return;
if(LAST_CHILD==pos)
{
m_childrenList.push_back(pChild);
}
else
{
std::vector<AccObject*>::iterator iter=m_childrenList.begin()+pos;
m_childrenList.insert(iter,pChild);
}
pChild->SetParentObj(this);
}
/**
* Delete a child element
* @param pChild Child element that should be inserted into child list.
* @param pos Insert postion.
* @return
*/
void AccObject::DeleteChild( AccObject* pChild )
{
std::vector<AccObject*>::iterator iter;
iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
if(iter!=m_childrenList.end())
{
m_childrenList.erase(iter);
if(m_pIMAcc)
pChild->SetParentObj(NULL);
}
}
/**
* In order to windows API WindowFromAccessibleObject,we sometimes to set a pure
* top window accessible object created by windows system as top ancestor.
* @param.
* @return
*/
void AccObject::UpdateValidWindow()
{
if(m_pIMAcc)
m_pIMAcc->Put_XAccWindowHandle(m_pParantID);
}
/**
* Translate all UNO basic information into MSAA com information.
* @param
* @return If the method is correctly processed.
*/
sal_Bool AccObject::ImplInitializeCreateObj()
{
m_pIMAcc = UAccCOMCreateInstance();
assert(m_pIMAcc);
return m_pIMAcc != 0;
}
/**
* Update name property to com object.
* @param
* @return
*/
void AccObject::UpdateName( )
{
if (!m_pIMAcc)
{
return;
}
if( ( TEXT_FRAME == m_accRole ) && ( m_pParentObj !=NULL )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) )
m_pIMAcc->Put_XAccName( m_pParentObj->m_xAccContextRef->getAccessibleName().getStr() );
//IAccessibility2 Implementation 2009-----
if ( PARAGRAPH == m_accRole)
{
::rtl::OUString emptyStr("");
m_pIMAcc->Put_XAccName(emptyStr.getStr());
}
//-----IAccessibility2 Implementation 2009
else
m_pIMAcc->Put_XAccName(m_xAccContextRef->getAccessibleName().getStr());
return ;
}
/**
* Update description property to com object.
* no content for update description
* @param
* @return
*/
void AccObject::UpdateDescription()
{
if (!m_pIMAcc)
{
return;
}
m_pIMAcc->Put_XAccDescription(m_xAccContextRef->getAccessibleDescription().getStr());
return ;
}
/**
* Update default action property to com object.
* @param
* @return
*/
void AccObject::UpdateAction()
{
m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
if( m_xAccActionRef.is() && m_pIMAcc )
{
if( m_xAccActionRef->getAccessibleActionCount() > 0 )
{
UpdateDefaultAction( );
m_pIMAcc->SetDefaultAction(
reinterpret_cast<hyper>(m_xAccActionRef.get()));
}
}
}
/**
* Update value property to com object.
* @param
* @return
*/
void AccObject::UpdateValue()
{
if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
{
assert(false);
return ;
}
Reference< XAccessibleValue > pRValue(m_xAccContextRef.get(),UNO_QUERY);
Any pAny;
if( pRValue.is() )
{
pAny = pRValue->getCurrentValue();
}
SetValue( pAny );
}
/**
* Set special default action description string via UNO role.
* @param Role UNO role
* @return
*/
void AccObject::UpdateDefaultAction( )
{
if(!m_xAccActionRef.is())
return ;
switch(m_accRole)
{
case PUSH_BUTTON:
case TOGGLE_BUTTON:
case RADIO_BUTTON:
case MENU_ITEM:
case RADIO_MENU_ITEM:
case CHECK_MENU_ITEM:
case LIST_ITEM:
case CHECK_BOX:
case TREE_ITEM:
case BUTTON_DROPDOWN:
m_pIMAcc->Put_ActionDescription( m_xAccActionRef->getAccessibleActionDescription((sal_Int32)0).getStr() );
return;
}
}
/**
* Set value property via pAny.
* @param pAny New value.
* @return
*/
void AccObject::SetValue( Any pAny )
{
unsigned short pUNumberString[100];
memset( pUNumberString, 0 , sizeof( pUNumberString) );
if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
{
assert(false);
return ;
}
Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY);
::rtl::OUString val;
int index = 0 ;
switch(m_accRole)
{
case SPIN_BOX:
// 3. date editor's msaa value should be the same as spinbox
case DATE_EDITOR:
case TEXT:
case PARAGRAPH:
case HEADING:
if(pRText.get())
{
val = pRText->getText();
}
m_pIMAcc->Put_XAccValue( val.getStr() );
break;
case TREE_ITEM:
//case CHECK_BOX: //Commented by Li Xing to disable the value for general checkbox
case COMBO_BOX:
case TABLE_CELL:
case NOTE:
case SCROLL_BAR:
m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
break ;
// Added by Li Xing, only the checkbox in tree should have the value.
case CHECK_BOX:
if( ( m_pParentObj !=NULL ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole ))
m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
break;
default:
break;
}
return;
}
::rtl::OUString AccObject::GetMAccessibleValueFromAny(Any pAny)
{
::rtl::OUString strValue;
if(NULL == m_pIMAcc)
return strValue;
if(pAny.getValueType() == getCppuType( (sal_uInt16 *)0 ) )
{
sal_uInt16 val;
if (pAny >>= val)
{
strValue=::rtl::OUString::valueOf((sal_Int32)val);
}
}
else if(pAny.getValueType() == getCppuType( (::rtl::OUString *)0 ) )
{
pAny >>= strValue ;
}
else if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) )
{
Sequence< ::rtl::OUString > val;
if (pAny >>= val)
{
int count = val.getLength();
for( int iIndex = 0;iIndex < count;iIndex++ )
{
strValue += val[iIndex];
}
}
}
else if(pAny.getValueType() == getCppuType( (double *)0 ) )
{
double val;
if (pAny >>= val)
{
strValue=::rtl::OUString::valueOf(val);
}
}
else if(pAny.getValueType() == getCppuType( (sal_Int32 *)0 ) )
{
sal_Int32 val;
if (pAny >>= val)
{
strValue=::rtl::OUString::valueOf(val);
}
}
else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) )
{
com::sun::star::accessibility::TextSegment val;
if (pAny >>= val)
{
::rtl::OUString realVal(val.SegmentText);
strValue = realVal;
}
}
return strValue;
}
/**
* Set name property via pAny.
* @param pAny New accessible name.
* @return
*/
void AccObject::SetName( Any pAny)
{
if( NULL == m_pIMAcc )
return ;
m_pIMAcc->Put_XAccName( GetMAccessibleValueFromAny(pAny).getStr() );
}
/**
* Set description property via pAny.
* @param pAny New accessible description.
* @return
*/
void AccObject::SetDescription( Any pAny )
{
if( NULL == m_pIMAcc )
return ;
m_pIMAcc->Put_XAccDescription( GetMAccessibleValueFromAny(pAny).getStr() );
}
/**
* Set role property via pAny
* @param Role New accessible role.
* @return
*/
void AccObject::SetRole( short Role )
{
if( NULL == m_pIMAcc )
return ;
m_pIMAcc->Put_XAccRole( Role );
}
/**
* Get role property via pAny
* @param
* @return accessible role
*/
short AccObject::GetRole() const
{
return m_accRole;
}
/**
* Get MSAA state from UNO state
* @Role xState UNO state.
* @return
*/
DWORD AccObject::GetMSAAStateFromUNO(short xState)
{
DWORD IState = UNO_MSAA_UNMAPPING;
if( !m_xAccContextRef.is() )
{
assert(false);
return IState;
}
short Role = m_accRole;
switch( xState )
{
case BUSY:
IState = STATE_SYSTEM_BUSY;
break;
case CHECKED:
if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON )
{
IState = STATE_SYSTEM_PRESSED;
}
else
IState = STATE_SYSTEM_CHECKED;
break;
case DEFUNC:
IState = STATE_SYSTEM_UNAVAILABLE;
break;
case EXPANDED:
IState = STATE_SYSTEM_EXPANDED;
break;
case FOCUSABLE:
IState = STATE_SYSTEM_FOCUSABLE;
break;
case FOCUSED:
IState = STATE_SYSTEM_FOCUSED;
break;
case INDETERMINATE:
IState = STATE_SYSTEM_MIXED;
break;
case MULTI_SELECTABLE:
IState = STATE_SYSTEM_MULTISELECTABLE;
break;
case PRESSED:
IState = STATE_SYSTEM_PRESSED;
break;
case RESIZABLE:
IState = STATE_SYSTEM_SIZEABLE;
break;
case SELECTABLE:
if( m_accRole == MENU || m_accRole == MENU_ITEM)
{
IState = UNO_MSAA_UNMAPPING;
}
else
{
IState = STATE_SYSTEM_SELECTABLE;
}
break;
case SELECTED:
if( m_accRole == MENU || m_accRole == MENU_ITEM )
{
IState = UNO_MSAA_UNMAPPING;
}
else
{
IState = STATE_SYSTEM_SELECTED;
}
break;
case ARMED:
IState = STATE_SYSTEM_FOCUSED;
break;
case EXPANDABLE:
{
sal_Bool isExpanded = sal_True;
sal_Bool isExpandable = sal_True;
if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON || BUTTON_DROPDOWN == Role )
{
IState = STATE_SYSTEM_HASPOPUP;
}
else
{
GetExpandedState(&isExpandable,&isExpanded);
if(!isExpanded)
IState = STATE_SYSTEM_COLLAPSED;
}
}
break;
//Remove the SENSITIVE state mapping. There is no corresponding MSAA state.
//case SENSITIVE:
// IState = STATE_SYSTEM_PROTECTED;
case EDITABLE:
if( m_pIMAcc )
{
m_pIMAcc->DecreaseState( STATE_SYSTEM_READONLY );
}
break;
case OFFSCREEN:
IState = STATE_SYSTEM_OFFSCREEN;
break;
case MOVEABLE:
IState = STATE_SYSTEM_MOVEABLE;
break;
case COLLAPSE:
IState = STATE_SYSTEM_COLLAPSED;
break;
case DEFAULT:
IState = STATE_SYSTEM_DEFAULT;
break;
default:
break;
}
return IState;
}
/**
* Decrease state of com object
* @param xState The lost state.
* @return
*/
void AccObject::DecreaseState( short xState )
{
if( NULL == m_pIMAcc )
{
return;
}
if( xState == FOCUSABLE)
{
short Role = m_accRole ;
if(Role == MENU_ITEM
|| Role == RADIO_MENU_ITEM
|| Role == CHECK_MENU_ITEM)
return;
else
{
if (Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
{
if( ( m_pParentObj !=NULL ) && (TOOL_BAR == m_pParentObj->m_accRole ) )
return;
}
}
}
else if( xState == AccessibleStateType::VISIBLE )
{
m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
}
else if( xState == AccessibleStateType::SHOWING )
{
m_pIMAcc->IncreaseState( STATE_SYSTEM_OFFSCREEN );
}
DWORD msState = GetMSAAStateFromUNO(xState);
if(msState!=UNO_MSAA_UNMAPPING)
m_pIMAcc->DecreaseState(msState);
}
/**
* Increase state of com object
* @param xState The new state.
* @return
*/
void AccObject::IncreaseState( short xState )
{
if( NULL == m_pIMAcc )
{
assert(false);
return;
}
if( xState == AccessibleStateType::VISIBLE )
{
m_pIMAcc->DecreaseState( STATE_SYSTEM_INVISIBLE );
}
else if( xState == AccessibleStateType::SHOWING )
{
m_pIMAcc->DecreaseState( STATE_SYSTEM_OFFSCREEN );
}
DWORD msState = GetMSAAStateFromUNO(xState);
if(msState!=UNO_MSAA_UNMAPPING)
m_pIMAcc->IncreaseState( msState );
}
/**
* Get next child element
* @param
* @return AccObject Object interface.
*/
AccObject* AccObject::NextChild()
{
IAccChildList::iterator pInd = m_childrenList.begin();
if( pInd != m_childrenList.end() )
return *pInd;
return NULL;
}
/**
* update action desciption desc
* @param
* @return
*/
void AccObject::UpdateActionDesc()
{
if (!m_pIMAcc)
{
return;
}
::rtl::OUString pXString = m_xAccContextRef->getAccessibleDescription();
m_pIMAcc->Put_XAccDescription(pXString.getStr());
long Role = m_accRole;
if( Role == PUSH_BUTTON || Role == RADIO_BUTTON || Role == MENU_ITEM ||
Role == LIST_ITEM || Role == CHECK_BOX || Role == TREE_ITEM ||
Role == CHECK_MENU_ITEM || Role == RADIO_MENU_ITEM )
{
UpdateDefaultAction( );
}
else
{
if( m_xAccActionRef.is() )
{
if( m_xAccActionRef->getAccessibleActionCount() > 0 )
{
if (!(Role == SPIN_BOX || Role == COMBO_BOX || Role == DATE_EDITOR ||
Role == EDIT_BAR || Role == PASSWORD_TEXT || Role == TEXT))
{
pXString = m_xAccActionRef->getAccessibleActionDescription( 0 );
//Solution:If string length is more than zero,action will will be set.
if( pXString.getLength() > 0)
m_pIMAcc->Put_ActionDescription( pXString.getStr() );
}
}
}
}
}
/**
* update role information from uno to com
* @param
* @return
*/
void AccObject::UpdateRole()
{
if (!m_pIMAcc)
{
return;
}
XAccessibleContext* pContext = m_xAccContextRef.get();
m_pIMAcc->Put_XAccRole( ROLE_SYSTEM_WINDOW );
short iRoleIndex = pContext->getAccessibleRole();
if (( 0 <= iRoleIndex) && ( iRoleIndex <= (sizeof(ROLE_TABLE)/(sizeof(short)*2))))
{
short iIA2Role = ROLE_TABLE[iRoleIndex][1] ;
m_pIMAcc->Put_XAccRole( iIA2Role );
}
}
/**
* update state information from uno to com
* @param
* @return
*/
void AccObject::UpdateState()
{
if (!m_pIMAcc)
{
return;
}
XAccessibleContext* pContext = m_xAccContextRef.get();
Reference< XAccessibleStateSet > pRState = pContext->getAccessibleStateSet();
if( !pRState.is() )
{
assert(false);
return ;
}
m_pIMAcc->SetState(0L);
if ( m_accRole == POPUP_MENU )
{
return;
}
Sequence<short> pStates = pRState->getStates();
int count = pStates.getLength();
sal_Bool isEnable = sal_False;
sal_Bool isShowing = sal_False;
sal_Bool isEditable = sal_False;
sal_Bool isVisible = sal_False;
sal_Bool isFocusable = sal_False;
for( int iIndex = 0;iIndex < count;iIndex++ )
{
if( pStates[iIndex] == ENABLED )
isEnable = sal_True;
else if( pStates[iIndex] == SHOWING)
isShowing = sal_True;
else if( pStates[iIndex] == VISIBLE)
isVisible = sal_True;
else if( pStates[iIndex] == EDITABLE )
isEditable = sal_True;
else if (pStates[iIndex] == FOCUSABLE)
isFocusable = sal_True;
IncreaseState( pStates[iIndex]);
}
sal_Bool bIsMenuItem = m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM;
if(bIsMenuItem)
{
if(!(isShowing && isVisible) )
{
m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
m_pIMAcc->DecreaseState( STATE_SYSTEM_FOCUSABLE );
}
}
else
{
if(!(isShowing || isVisible) )
m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
}
short Role = m_accRole;
if( m_pIMAcc )
{
switch(m_accRole)
{
case LABEL:
m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
break;
case TEXT:
// 2. editable combobox -> readonly ------ bridge
case EMBEDDED_OBJECT:
case END_NOTE:
case FOOTER:
case FOOTNOTE:
case GRAPHIC:
case HEADER:
case HEADING:
//Image Map
case PARAGRAPH:
case PASSWORD_TEXT:
case SHAPE:
case SPIN_BOX:
case TABLE:
case TABLE_CELL:
case TEXT_FRAME:
case DATE_EDITOR:
case DOCUMENT:
case COLUMN_HEADER:
{
if(!isEditable)
m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
}
break;
default:
break;
}
}
if( isEnable )
{
if(!(Role == FILLER || Role == END_NOTE || Role == FOOTER || Role == FOOTNOTE || Role == GROUP_BOX || Role == RULER
|| Role == HEADER || Role == ICON || Role == INTERNAL_FRAME || Role == LABEL || Role == LAYERED_PANE
|| Role == SCROLL_BAR || Role == SCROLL_PANE || Role == SPLIT_PANE || Role == STATUS_BAR || Role == TOOL_TIP))
{
if( SEPARATOR == Role )
{
if( ( m_pParentObj != NULL ) && ( MENU == m_pParentObj->m_accRole || POPUP_MENU == m_pParentObj->m_accRole ))
IncreaseState( FOCUSABLE );
}
else if (TABLE_CELL == Role || TABLE == Role || PANEL == Role || OPTION_PANE == Role ||
COLUMN_HEADER == Role)
{
if (isFocusable)
IncreaseState( FOCUSABLE );
}
else
{
if(bIsMenuItem)
{
if ( isShowing && isVisible)
{
IncreaseState( FOCUSABLE );
}
}
else
{
IncreaseState( FOCUSABLE );
}
}
}
}
else
{
m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE );
sal_Bool isDecreaseFocusable = sal_False;
if( !((Role == MENU_ITEM) ||
(Role == RADIO_MENU_ITEM) ||
(Role == CHECK_MENU_ITEM)) )
{
if ( Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
{
if(( m_pParentObj != NULL )&& (TOOL_BAR == m_pParentObj->m_accRole ) )
IncreaseState( FOCUSABLE );
else
DecreaseState( FOCUSABLE );
}
else
DecreaseState( FOCUSABLE );
}
else if( isShowing || isVisible )
{
IncreaseState( FOCUSABLE );
}
}
if( m_pIMAcc )
{
switch(m_accRole)
{
case POPUP_MENU:
case MENU:
if( pContext->getAccessibleChildCount() > 0 )
m_pIMAcc->IncreaseState( STATE_SYSTEM_HASPOPUP );
break;
case PASSWORD_TEXT:
m_pIMAcc->IncreaseState( STATE_SYSTEM_PROTECTED );
break;
default:
break;
}
}
}
/**
* update location information from uno to com
* @param
* @return
*/
void AccObject::UpdateLocation()
{
if (!m_pIMAcc)
{
return;
}
XAccessibleContext* pContext = m_xAccContextRef.get();
Reference< XAccessibleComponent > pRComponent(pContext,UNO_QUERY);
if( pRComponent.is() )
{
::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen();
::com::sun::star::awt::Size pCSize = pRComponent->getSize();
Location tempLocation;
tempLocation.m_dLeft = pCPoint.X;
tempLocation.m_dTop = pCPoint.Y;
tempLocation.m_dWidth = pCSize.Width;
tempLocation.m_dHeight = pCSize.Height;
m_pIMAcc->Put_XAccLocation( tempLocation );
}
}
/**
* Public method to mapping information between MSAA and UNO.
* @param
* @return If the method is correctly processed.
*/
sal_Bool AccObject:: UpdateAccessibleInfoFromUnoToMSAA ( )
{
if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
{
assert(false);
return sal_False;
}
UpdateName();
UpdateValue();
UpdateActionDesc();
UpdateRole();
UpdateLocation();
UpdateState();
return sal_True;
}
/*
* Add a child selected element.
* @param pAccObj Child object pointer.
* @return
*/
void AccObject::AddSelect( long index, AccObject* accObj)
{
m_selectionList.insert(IAccSelectionList::value_type(index,accObj));
}
IAccSelectionList& AccObject::GetSelection()
{
return m_selectionList;
}
/**
* Set self to focus object in parant child list
* @param
* @return
*/
void AccObject::setFocus()
{
if(m_pIMAcc)
{
IncreaseState(FOCUSED);
m_pIMAcc->Put_XAccFocus(CHILDID_SELF);
UpdateRole();
}
}
/**
* Unset self from focus object in parant child list.
* @param
* @return
*/
void AccObject::unsetFocus()
{
if(m_pIMAcc)
{
DecreaseState( FOCUSED );
m_pIMAcc->Put_XAccFocus(UACC_NO_FOCUS);
}
}
void AccObject::GetExpandedState( sal_Bool* isExpandable, sal_Bool* isExpanded)
{
*isExpanded = sal_False;
*isExpandable = sal_False;
if( !m_xAccContextRef.is() )
{
return;
}
Reference< XAccessibleStateSet > pRState = m_xAccContextRef->getAccessibleStateSet();
if( !pRState.is() )
{
return;
}
Sequence<short> pStates = pRState->getStates();
int count = pStates.getLength();
for( int iIndex = 0;iIndex < count;iIndex++ )
{
if( EXPANDED == pStates[iIndex] )
{
*isExpanded = sal_True;
}
else if( EXPANDABLE == pStates[iIndex] )
{
*isExpandable = sal_True;
}
}
}
void AccObject::NotifyDestroy(sal_Bool ifDelete)
{
m_bShouldDestroy=ifDelete;
if(m_pIMAcc)
m_pIMAcc->NotifyDestroy(m_bShouldDestroy);
}
void AccObject::SetParentObj(AccObject* pParentAccObj)
{
m_pParentObj = pParentAccObj;
if(m_pIMAcc)
{
if(m_pParentObj)
{
m_pIMAcc->Put_XAccParent(m_pParentObj->GetIMAccessible());
}
else
{
m_pIMAcc->Put_XAccParent(NULL);
}
}
}
//ResID means ChildID in MSAA
void AccObject::SetResID(long id)
{
m_resID = id;
if(m_pIMAcc)
m_pIMAcc->Put_XAccChildID(m_resID);
}
//return COM interface in acc object
IMAccessible* AccObject::GetIMAccessible()
{
return m_pIMAcc;
}
Reference < XAccessible > AccObject::GetXAccessible()
{
return m_xAccRef;
}
void AccObject::SetParentHWND(HWND hWnd)
{
m_pParantID = hWnd;
}
void AccObject::SetListener( AccEventListener* Listener )
{
m_accListener = Listener;
}
AccEventListener* AccObject::getListener()
{
return m_accListener;
}
long AccObject::GetResID()
{
return m_resID;
}
HWND AccObject::GetParentHWND()
{
return m_pParantID;
}
AccObject* AccObject::GetParentObj()
{
return m_pParentObj;
}
sal_Bool AccObject::ifShouldDestroy()
{
return m_bShouldDestroy;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */