Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / winaccessibility / source / service / AccObject.cxx
blob68dcc10105f221982b84ac10b736879f36142c40
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/uno/Sequence.h>
21 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
22 #include <com/sun/star/accessibility/AccessibleRole.hpp>
23 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
24 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
25 #include <com/sun/star/accessibility/XAccessibleText.hpp>
27 #include <o3tl/char16_t2wchar_t.hxx>
28 #include <o3tl/safeint.hxx>
30 #include <stdlib.h>
31 #include <memory.h>
32 #include <stdio.h>
33 #include <algorithm>
34 #include <assert.h>
36 #include <AccObject.hxx>
37 #include <AccEventListener.hxx>
39 #if defined __clang__
40 #pragma clang diagnostic push
41 #pragma clang diagnostic ignored "-Wextra-tokens"
42 // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
43 #endif
44 #include <UAccCOM_i.c>
45 #if defined __clang__
46 #pragma clang diagnostic pop
47 #endif
49 using namespace com::sun::star::uno;
50 using namespace com::sun::star::accessibility;
51 using namespace com::sun::star::accessibility::AccessibleRole;
52 using namespace com::sun::star::accessibility::AccessibleStateType;
54 //Role mapping table,left side is UNO role, right side is MSAA role
55 const short ROLE_TABLE[][2] =
57 {UNKNOWN, IA2_ROLE_UNKNOWN},
58 {ALERT , ROLE_SYSTEM_DIALOG},
59 {COLUMN_HEADER , ROLE_SYSTEM_COLUMNHEADER},
60 //{CANVAS , ROLE_SYSTEM_CLIENT},
61 {CANVAS , IA2_ROLE_CANVAS},
62 {CHECK_BOX , ROLE_SYSTEM_CHECKBUTTON},
63 {CHECK_MENU_ITEM , IA2_ROLE_CHECK_MENU_ITEM},
64 {COLOR_CHOOSER, IA2_ROLE_COLOR_CHOOSER},
65 {COMBO_BOX , ROLE_SYSTEM_COMBOBOX},
66 {DATE_EDITOR , IA2_ROLE_DATE_EDITOR},
67 {DESKTOP_ICON , IA2_ROLE_DESKTOP_ICON},
68 {DESKTOP_PANE, IA2_ROLE_DESKTOP_PANE},
69 {DIRECTORY_PANE, IA2_ROLE_DIRECTORY_PANE},
70 {DIALOG, ROLE_SYSTEM_DIALOG},
71 {DOCUMENT, ROLE_SYSTEM_DOCUMENT},
72 {EMBEDDED_OBJECT , IA2_ROLE_EMBEDDED_OBJECT },
73 {END_NOTE , IA2_ROLE_ENDNOTE },
74 {FILE_CHOOSER , IA2_ROLE_FILE_CHOOSER },
75 {FILLER, ROLE_SYSTEM_WHITESPACE},
76 {FONT_CHOOSER, IA2_ROLE_FONT_CHOOSER},
77 {FOOTER, IA2_ROLE_FOOTER},
78 {FOOTNOTE, IA2_ROLE_FOOTNOTE},
79 //{FRAME, IA2_ROLE_FRAME},
80 {FRAME, ROLE_SYSTEM_DIALOG},
81 {GLASS_PANE , IA2_ROLE_GLASS_PANE},
82 {GRAPHIC , ROLE_SYSTEM_GRAPHIC},
83 {GROUP_BOX, ROLE_SYSTEM_GROUPING},
84 {HEADER , IA2_ROLE_HEADER},
85 {HEADING , IA2_ROLE_HEADING},
86 {HYPER_LINK , ROLE_SYSTEM_TEXT},
87 {ICON , IA2_ROLE_ICON},
88 {INTERNAL_FRAME, IA2_ROLE_INTERNAL_FRAME},
89 {LABEL, ROLE_SYSTEM_STATICTEXT},
90 {LAYERED_PANE , IA2_ROLE_LAYERED_PANE},
91 {LIST , ROLE_SYSTEM_LIST},
92 {LIST_ITEM , ROLE_SYSTEM_LISTITEM},
93 //{MENU , ROLE_SYSTEM_MENUPOPUP},
94 {MENU, ROLE_SYSTEM_MENUITEM},
95 {MENU_BAR, ROLE_SYSTEM_MENUBAR},
96 {MENU_ITEM, ROLE_SYSTEM_MENUITEM},
97 {OPTION_PANE , IA2_ROLE_OPTION_PANE},
98 {PAGE_TAB, ROLE_SYSTEM_PAGETAB},
99 {PAGE_TAB_LIST, ROLE_SYSTEM_PAGETABLIST},
100 {PANEL, IA2_ROLE_OPTION_PANE},
101 {PARAGRAPH, IA2_ROLE_PARAGRAPH},
102 {PASSWORD_TEXT, ROLE_SYSTEM_TEXT},
103 {POPUP_MENU, ROLE_SYSTEM_MENUPOPUP},
104 {PUSH_BUTTON, ROLE_SYSTEM_PUSHBUTTON},
105 {PROGRESS_BAR, ROLE_SYSTEM_PROGRESSBAR},
106 {RADIO_BUTTON, ROLE_SYSTEM_RADIOBUTTON},
107 {RADIO_MENU_ITEM, IA2_ROLE_RADIO_MENU_ITEM},
108 {ROW_HEADER , ROLE_SYSTEM_ROWHEADER},
109 {ROOT_PANE, IA2_ROLE_ROOT_PANE},
110 {SCROLL_BAR , ROLE_SYSTEM_SCROLLBAR},
111 {SCROLL_PANE , IA2_ROLE_SCROLL_PANE},
112 {SHAPE, IA2_ROLE_SHAPE},
113 {SEPARATOR , ROLE_SYSTEM_SEPARATOR},
114 {SLIDER , ROLE_SYSTEM_SLIDER},
115 {SPIN_BOX , ROLE_SYSTEM_SPINBUTTON},
116 {SPLIT_PANE, IA2_ROLE_SPLIT_PANE},
117 {STATUS_BAR, ROLE_SYSTEM_STATUSBAR},
118 {TABLE, ROLE_SYSTEM_TABLE},
119 {TABLE_CELL , ROLE_SYSTEM_CELL},
120 {TEXT, ROLE_SYSTEM_TEXT},
121 {TEXT_FRAME , IA2_ROLE_TEXT_FRAME},
122 //for change toggle button to push button for jaws
123 {TOGGLE_BUTTON, ROLE_SYSTEM_PUSHBUTTON},
125 {TOOL_BAR, ROLE_SYSTEM_TOOLBAR},
126 {TOOL_TIP, ROLE_SYSTEM_TOOLTIP},
127 {TREE , ROLE_SYSTEM_OUTLINE},
128 {VIEW_PORT , IA2_ROLE_VIEW_PORT},
129 {WINDOW, ROLE_SYSTEM_WINDOW},
130 {BUTTON_DROPDOWN, ROLE_SYSTEM_BUTTONDROPDOWN},
131 {BUTTON_MENU, ROLE_SYSTEM_BUTTONMENU},
132 {CAPTION, IA2_ROLE_CAPTION},
133 {CHART, IA2_ROLE_SHAPE},
134 {EDIT_BAR, IA2_ROLE_EDITBAR},
135 {FORM, IA2_ROLE_FORM},
136 {IMAGE_MAP , IA2_ROLE_IMAGE_MAP},
137 {NOTE, IA2_ROLE_NOTE},
138 {PAGE, IA2_ROLE_PAGE},
139 {RULER , IA2_ROLE_RULER},
140 {SECTION, IA2_ROLE_SECTION},
141 {TREE_ITEM , ROLE_SYSTEM_OUTLINEITEM},
142 {TREE_TABLE, ROLE_SYSTEM_OUTLINE},
143 {COMMENT, IA2_ROLE_TEXT_FRAME },
144 {COMMENT_END, IA2_ROLE_TEXT_FRAME },
145 {DOCUMENT_PRESENTATION, ROLE_SYSTEM_DOCUMENT },
146 {DOCUMENT_SPREADSHEET, ROLE_SYSTEM_DOCUMENT },
147 {DOCUMENT_TEXT, ROLE_SYSTEM_DOCUMENT },
148 {STATIC, ROLE_SYSTEM_STATICTEXT },
149 {NOTIFICATION, ROLE_SYSTEM_ALERT}
154 * Constructor.
155 * @param pXAcc Uno XAccessible interface of control.
156 * @param Agent The agent kept in all listeners,it's the sole interface by which
157 * listener communicate with windows manager.
158 * @param listener listener that registers in UNO system.
159 * @return.
161 AccObject::AccObject(XAccessible* pAcc, AccObjectManagerAgent* pAgent,
162 AccEventListener* pListener) :
163 m_resID (0),
164 m_pParantID (nullptr),
165 m_pIMAcc (UAccCOMCreateInstance()),
166 m_pParentObj(nullptr),
167 m_pListener (pListener),
168 m_xAccRef( pAcc )
170 ImplInitializeCreateObj();
172 m_xAccContextRef = m_xAccRef->getAccessibleContext();
173 m_xAccActionRef.set(m_xAccContextRef,UNO_QUERY);
174 m_accRole = m_xAccContextRef -> getAccessibleRole();
175 if( m_pIMAcc )
177 m_pIMAcc->SetXAccessible(reinterpret_cast<hyper>(m_xAccRef.get()));
178 m_pIMAcc->Put_XAccAgent(reinterpret_cast<hyper>(pAgent));
179 m_pIMAcc->SetDefaultAction(reinterpret_cast<hyper>(m_xAccActionRef.get()));
183 * Destructor.
184 * @param
185 * @return
187 AccObject::~AccObject()
189 m_xAccRef = nullptr;
190 m_xAccActionRef = nullptr;
191 m_xAccContextRef = nullptr;
196 * Insert a child element.
197 * @param pChild Child element that should be inserted into child list.
198 * @param pos Insert position.
199 * @return
201 void AccObject::InsertChild( AccObject* pChild,short pos )
204 std::vector<AccObject*>::iterator iter;
205 iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
206 if(iter!=m_childrenList.end())
207 return;
208 if(LAST_CHILD==pos)
210 m_childrenList.push_back(pChild);
212 else
214 iter=m_childrenList.begin()+pos;
215 m_childrenList.insert(iter,pChild);
218 pChild->SetParentObj(this);
222 * Delete a child element
223 * @param pChild Child element that should be inserted into child list.
224 * @param pos Insert position.
225 * @return
227 void AccObject::DeleteChild( AccObject* pChild )
229 std::vector<AccObject*>::iterator iter;
230 iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
231 if(iter!=m_childrenList.end())
233 m_childrenList.erase(iter);
234 if(m_pIMAcc)
235 pChild->SetParentObj(nullptr);
240 * In order to windows API WindowFromAccessibleObject, we sometimes to set a pure
241 * top window accessible object created by windows system as top ancestor.
242 * @param.
243 * @return
245 void AccObject::UpdateValidWindow()
247 if(m_pIMAcc)
248 m_pIMAcc->Put_XAccWindowHandle(m_pParantID);
252 * Translate all UNO basic information into MSAA com information.
253 * @param
254 * @return If the method is correctly processed.
256 void AccObject::ImplInitializeCreateObj()
258 assert(m_pIMAcc);
262 * Update name property to com object.
263 * @param
264 * @return
266 void AccObject::UpdateName( )
268 if (!m_pIMAcc)
270 return;
273 if( ( TEXT_FRAME == m_accRole ) && ( m_pParentObj !=nullptr )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) )
274 m_pIMAcc->Put_XAccName( o3tl::toW(m_pParentObj->m_xAccContextRef->getAccessibleName().getStr()) );
275 //IAccessibility2 Implementation 2009-----
276 if ( PARAGRAPH == m_accRole)
278 m_pIMAcc->Put_XAccName(L"");
280 //-----IAccessibility2 Implementation 2009
281 else
282 m_pIMAcc->Put_XAccName(o3tl::toW(m_xAccContextRef->getAccessibleName().getStr()));
284 return ;
288 * Update default action property to com object.
289 * @param
290 * @return
292 void AccObject::UpdateAction()
294 m_xAccActionRef.set(m_xAccContextRef,UNO_QUERY);
296 if( m_xAccActionRef.is() && m_pIMAcc )
298 if( m_xAccActionRef->getAccessibleActionCount() > 0 )
300 UpdateDefaultAction( );
301 m_pIMAcc->SetDefaultAction(
302 reinterpret_cast<hyper>(m_xAccActionRef.get()));
308 * Update value property to com object.
309 * @param
310 * @return
312 void AccObject::UpdateValue()
314 if( nullptr == m_pIMAcc || !m_xAccContextRef.is() )
316 assert(false);
317 return ;
320 Reference< XAccessibleValue > pRValue(m_xAccContextRef,UNO_QUERY);
321 Any pAny;
322 if( pRValue.is() )
324 pAny = pRValue->getCurrentValue();
327 SetValue( pAny );
331 * Set special default action description string via UNO role.
332 * @param Role UNO role
333 * @return
335 void AccObject::UpdateDefaultAction( )
337 if(!m_xAccActionRef.is())
338 return ;
340 switch(m_accRole)
342 case PUSH_BUTTON:
343 case TOGGLE_BUTTON:
344 case RADIO_BUTTON:
345 case MENU_ITEM:
346 case RADIO_MENU_ITEM:
347 case CHECK_MENU_ITEM:
348 case LIST_ITEM:
349 case CHECK_BOX:
350 case TREE_ITEM:
351 case BUTTON_DROPDOWN:
352 m_pIMAcc->Put_ActionDescription( o3tl::toW(m_xAccActionRef->getAccessibleActionDescription(sal_Int32(0)).getStr()) );
353 return;
358 * Set value property via pAny.
359 * @param pAny New value.
360 * @return
362 void AccObject::SetValue( Any pAny )
364 if( nullptr == m_pIMAcc || !m_xAccContextRef.is() )
366 assert(false);
367 return ;
369 Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY);
370 OUString val;
371 switch(m_accRole)
373 case SPIN_BOX:
374 // 3. date editor's msaa value should be the same as spinbox
375 case DATE_EDITOR:
376 case TEXT:
377 case PARAGRAPH:
378 case HEADING:
379 case TABLE_CELL:
381 if(pRText)
383 val = pRText->getText();
385 m_pIMAcc->Put_XAccValue( o3tl::toW(val.getStr()) );
386 break;
387 case TREE_ITEM:
388 //case CHECK_BOX: //Commented by Li Xing to disable the value for general checkbox
389 case COMBO_BOX:
390 case NOTE:
391 case SCROLL_BAR:
392 m_pIMAcc->Put_XAccValue( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) );
393 break ;
394 // Added by Li Xing, only the checkbox in tree should have the value.
395 case CHECK_BOX:
396 if( ( m_pParentObj !=nullptr ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole ))
397 m_pIMAcc->Put_XAccValue( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) );
398 break;
399 default:
400 break;
403 return;
406 OUString AccObject::GetMAccessibleValueFromAny(Any pAny)
408 OUString strValue;
410 if(nullptr == m_pIMAcc)
411 return strValue;
413 if(pAny.getValueType() == cppu::UnoType<cppu::UnoUnsignedShortType>::get() )
415 sal_uInt16 val;
416 if (pAny >>= val)
418 strValue=OUString::number(val);
422 else if(pAny.getValueType() == cppu::UnoType<OUString>::get())
425 pAny >>= strValue ;
428 else if(pAny.getValueType() == cppu::UnoType<Sequence< OUString >>::get())
430 Sequence< OUString > val;
431 if (pAny >>= val)
433 for (const OUString& rElem : val)
434 strValue += rElem;
437 else if(pAny.getValueType() == cppu::UnoType<double>::get())
439 double val;
440 if (pAny >>= val)
442 strValue=OUString::number(val);
445 else if(pAny.getValueType() == cppu::UnoType<sal_Int32>::get())
447 sal_Int32 val;
448 if (pAny >>= val)
450 strValue=OUString::number(val);
453 else if (pAny.getValueType() == cppu::UnoType<css::accessibility::TextSegment>::get())
455 css::accessibility::TextSegment val;
456 if (pAny >>= val)
458 OUString realVal(val.SegmentText);
459 strValue = realVal;
464 return strValue;
467 * Set name property via pAny.
468 * @param pAny New accessible name.
469 * @return
471 void AccObject::SetName( Any pAny)
473 if( nullptr == m_pIMAcc )
474 return ;
476 m_pIMAcc->Put_XAccName( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) );
481 * Get role property via pAny
482 * @param
483 * @return accessible role
485 short AccObject::GetRole() const
487 return m_accRole;
491 * Get MSAA state from UNO state
492 * @Role nState UNO state.
493 * @return
495 DWORD AccObject::GetMSAAStateFromUNO(sal_Int64 nState)
497 DWORD IState = UNO_MSAA_UNMAPPING;
499 if( !m_xAccContextRef.is() )
501 assert(false);
502 return IState;
504 short Role = m_accRole;
506 switch( nState )
508 case BUSY:
509 IState = STATE_SYSTEM_BUSY;
510 break;
511 case CHECKED:
512 if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON )
514 IState = STATE_SYSTEM_PRESSED;
516 else
517 IState = STATE_SYSTEM_CHECKED;
518 break;
519 case DEFUNC:
520 IState = STATE_SYSTEM_UNAVAILABLE;
521 break;
522 case EXPANDED:
523 IState = STATE_SYSTEM_EXPANDED;
524 break;
525 case FOCUSABLE:
526 IState = STATE_SYSTEM_FOCUSABLE;
527 break;
528 case FOCUSED:
529 IState = STATE_SYSTEM_FOCUSED;
530 break;
531 case INDETERMINATE:
532 IState = STATE_SYSTEM_MIXED;
533 break;
534 case MULTI_SELECTABLE:
535 IState = STATE_SYSTEM_MULTISELECTABLE;
536 break;
537 case PRESSED:
538 IState = STATE_SYSTEM_PRESSED;
539 break;
540 case RESIZABLE:
541 IState = STATE_SYSTEM_SIZEABLE;
542 break;
543 case SELECTABLE:
544 if( m_accRole == MENU || m_accRole == MENU_ITEM)
546 IState = UNO_MSAA_UNMAPPING;
548 else
550 IState = STATE_SYSTEM_SELECTABLE;
552 break;
553 case SELECTED:
554 if( m_accRole == MENU || m_accRole == MENU_ITEM )
556 IState = UNO_MSAA_UNMAPPING;
558 else
560 IState = STATE_SYSTEM_SELECTED;
562 break;
563 case ARMED:
564 IState = STATE_SYSTEM_FOCUSED;
565 break;
566 case EXPANDABLE:
568 sal_Bool isExpanded = true;
569 sal_Bool isExpandable = true;
570 if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON || BUTTON_DROPDOWN == Role )
572 IState = STATE_SYSTEM_HASPOPUP;
574 else
576 GetExpandedState(&isExpandable,&isExpanded);
577 if(!isExpanded)
578 IState = STATE_SYSTEM_COLLAPSED;
581 break;
582 //Remove the SENSITIVE state mapping. There is no corresponding MSAA state.
583 //case SENSITIVE:
584 // IState = STATE_SYSTEM_PROTECTED;
585 case EDITABLE:
586 if( m_pIMAcc )
588 m_pIMAcc->DecreaseState( STATE_SYSTEM_READONLY );
590 break;
591 case OFFSCREEN:
592 IState = STATE_SYSTEM_OFFSCREEN;
593 break;
594 case MOVEABLE:
595 IState = STATE_SYSTEM_MOVEABLE;
596 break;
597 case COLLAPSE:
598 IState = STATE_SYSTEM_COLLAPSED;
599 break;
600 case DEFAULT:
601 IState = STATE_SYSTEM_DEFAULT;
602 break;
603 default:
604 break;
607 return IState;
611 * Decrease state of com object
612 * @param xState The lost state.
613 * @return
615 void AccObject::DecreaseState( sal_Int64 xState )
617 if( nullptr == m_pIMAcc )
619 return;
622 if( xState == FOCUSABLE)
624 short Role = m_accRole ;
625 if(Role == MENU_ITEM
626 || Role == RADIO_MENU_ITEM
627 || Role == CHECK_MENU_ITEM)
628 return;
629 else
631 if (Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
633 if( ( m_pParentObj !=nullptr ) && (TOOL_BAR == m_pParentObj->m_accRole ) )
634 return;
639 else if( xState == AccessibleStateType::VISIBLE )
641 m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
643 else if( xState == AccessibleStateType::SHOWING )
645 m_pIMAcc->IncreaseState( STATE_SYSTEM_OFFSCREEN );
648 DWORD msState = GetMSAAStateFromUNO(xState);
649 if(msState!=UNO_MSAA_UNMAPPING)
650 m_pIMAcc->DecreaseState(msState);
654 * Increase state of com object
655 * @param xState The new state.
656 * @return
658 void AccObject::IncreaseState( sal_Int64 xState )
660 if( nullptr == m_pIMAcc )
662 assert(false);
663 return;
667 if( xState == AccessibleStateType::VISIBLE )
669 m_pIMAcc->DecreaseState( STATE_SYSTEM_INVISIBLE );
671 else if( xState == AccessibleStateType::SHOWING )
673 m_pIMAcc->DecreaseState( STATE_SYSTEM_OFFSCREEN );
677 DWORD msState = GetMSAAStateFromUNO(xState);
678 if(msState!=UNO_MSAA_UNMAPPING)
679 m_pIMAcc->IncreaseState( msState );
683 * Get next child element
684 * @param
685 * @return AccObject Object interface.
687 AccObject* AccObject::NextChild()
689 IAccChildList::iterator pInd = m_childrenList.begin();
690 if( pInd != m_childrenList.end() )
691 return *pInd;
692 return nullptr;
695 * update action description desc
696 * @param
697 * @return
699 void AccObject::UpdateActionDesc()
701 if (!m_pIMAcc)
702 return;
704 long Role = m_accRole;
706 if( Role == PUSH_BUTTON || Role == RADIO_BUTTON || Role == MENU_ITEM ||
707 Role == LIST_ITEM || Role == CHECK_BOX || Role == TREE_ITEM ||
708 Role == CHECK_MENU_ITEM || Role == RADIO_MENU_ITEM )
710 UpdateDefaultAction( );
712 else
715 if( m_xAccActionRef.is() )
717 if( m_xAccActionRef->getAccessibleActionCount() > 0 )
719 if (!(Role == SPIN_BOX || Role == COMBO_BOX || Role == DATE_EDITOR ||
720 Role == EDIT_BAR || Role == PASSWORD_TEXT || Role == TEXT))
722 const OUString sActionDesc = m_xAccActionRef->getAccessibleActionDescription(0);
723 // if string is non-empty, action is set.
724 if (!sActionDesc.isEmpty())
725 m_pIMAcc->Put_ActionDescription(o3tl::toW(sActionDesc.getStr()));
733 * update role information from uno to com
734 * @param
735 * @return
737 void AccObject::UpdateRole()
739 if (!m_pIMAcc)
741 return;
744 XAccessibleContext* pContext = m_xAccContextRef.get();
745 m_pIMAcc->Put_XAccRole( ROLE_SYSTEM_WINDOW );
746 sal_Int16 iRoleIndex = pContext->getAccessibleRole();
747 if ((0 <= iRoleIndex) && (o3tl::make_unsigned(iRoleIndex) < SAL_N_ELEMENTS(ROLE_TABLE)))
749 short iIA2Role = ROLE_TABLE[iRoleIndex][1] ;
750 m_pIMAcc->Put_XAccRole( iIA2Role );
755 * update state information from uno to com
756 * @param
757 * @return
759 void AccObject::UpdateState()
761 if (!m_pIMAcc)
763 return;
766 XAccessibleContext* pContext = m_xAccContextRef.get();
767 sal_Int64 nRState = pContext->getAccessibleStateSet();
769 m_pIMAcc->SetState(0);
771 if ( m_accRole == POPUP_MENU )
773 return;
776 bool isEnable = false;
777 bool isShowing = false;
778 bool isEditable = false;
779 bool isVisible = false;
780 bool isFocusable = false;
782 for (int i=0; i<63; ++i)
784 sal_Int64 nState = sal_Int64(1) << i;
785 if (!(nState & nRState))
786 continue;
787 if (nState == ENABLED)
788 isEnable = true;
789 else if (nState == SHOWING)
790 isShowing = true;
791 else if (nState == VISIBLE)
792 isVisible = true;
793 else if (nState == EDITABLE)
794 isEditable = true;
795 else if (nState == FOCUSABLE)
796 isFocusable = true;
797 IncreaseState(nState);
800 bool bIsMenuItem = m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM;
802 if(bIsMenuItem)
804 if(!(isShowing && isVisible) )
806 m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
807 m_pIMAcc->DecreaseState( STATE_SYSTEM_FOCUSABLE );
810 else
812 if(!(isShowing || isVisible) )
813 m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
816 short Role = m_accRole;
818 switch(m_accRole)
820 case LABEL:
821 case STATIC:
822 case NOTIFICATION:
823 m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
824 break;
825 case TEXT:
826 // 2. editable combobox -> readonly ------ bridge
827 case EMBEDDED_OBJECT:
828 case END_NOTE:
829 case FOOTER:
830 case FOOTNOTE:
831 case GRAPHIC:
832 case HEADER:
833 case HEADING:
835 //Image Map
836 case PARAGRAPH:
837 case PASSWORD_TEXT:
838 case SHAPE:
839 case SPIN_BOX:
840 case TABLE:
841 case TABLE_CELL:
842 case TEXT_FRAME:
843 case DATE_EDITOR:
844 case DOCUMENT:
845 case COLUMN_HEADER:
847 if(!isEditable)
848 m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
850 break;
851 default:
852 break;
855 if( isEnable )
858 if(!(Role == FILLER || Role == END_NOTE || Role == FOOTER || Role == FOOTNOTE || Role == GROUP_BOX || Role == RULER
859 || Role == HEADER || Role == ICON || Role == INTERNAL_FRAME || Role == LABEL || Role == LAYERED_PANE
860 || Role == SCROLL_BAR || Role == SCROLL_PANE || Role == SPLIT_PANE || Role == STATIC || Role == STATUS_BAR
861 || Role == TOOL_TIP || Role == NOTIFICATION))
863 if( SEPARATOR == Role )
865 if( ( m_pParentObj != nullptr ) && ( MENU == m_pParentObj->m_accRole || POPUP_MENU == m_pParentObj->m_accRole ))
866 IncreaseState( FOCUSABLE );
869 else if (TABLE_CELL == Role || TABLE == Role || PANEL == Role || OPTION_PANE == Role ||
870 COLUMN_HEADER == Role)
872 if (isFocusable)
873 IncreaseState( FOCUSABLE );
875 else
877 if(bIsMenuItem)
879 if ( isShowing && isVisible)
881 IncreaseState( FOCUSABLE );
884 else
886 IncreaseState( FOCUSABLE );
891 else
893 m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE );
894 if( !((Role == MENU_ITEM) ||
895 (Role == RADIO_MENU_ITEM) ||
896 (Role == CHECK_MENU_ITEM)) )
898 if ( Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
900 if(( m_pParentObj != nullptr )&& (TOOL_BAR == m_pParentObj->m_accRole ) )
901 IncreaseState( FOCUSABLE );
902 else
903 DecreaseState( FOCUSABLE );
905 else
906 DecreaseState( FOCUSABLE );
908 else if( isShowing || isVisible )
910 IncreaseState( FOCUSABLE );
914 switch(m_accRole)
916 case POPUP_MENU:
917 case MENU:
918 if( pContext->getAccessibleChildCount() > 0 )
919 m_pIMAcc->IncreaseState( STATE_SYSTEM_HASPOPUP );
920 break;
921 case PASSWORD_TEXT:
922 m_pIMAcc->IncreaseState( STATE_SYSTEM_PROTECTED );
923 break;
924 default:
925 break;
930 * Public method to mapping information between MSAA and UNO.
931 * @param
932 * @return If the method is correctly processed.
934 bool AccObject::UpdateAccessibleInfoFromUnoToMSAA()
936 if( nullptr == m_pIMAcc || !m_xAccContextRef.is() )
938 assert(false);
939 return false;
942 UpdateName();
944 UpdateValue();
946 UpdateActionDesc();
948 UpdateRole();
950 UpdateState();
952 return true;
957 * Set self to focus object in parent child list
958 * @param
959 * @return
961 void AccObject::setFocus()
963 if(m_pIMAcc)
965 IncreaseState(FOCUSED);
966 m_pIMAcc->Put_XAccFocus(CHILDID_SELF);
968 UpdateRole();
973 * Unset self from focus object in parent child list.
974 * @param
975 * @return
977 void AccObject::unsetFocus()
979 if(m_pIMAcc)
981 DecreaseState( FOCUSED );
982 m_pIMAcc->Put_XAccFocus(UACC_NO_FOCUS);
986 void AccObject::GetExpandedState( sal_Bool* isExpandable, sal_Bool* isExpanded)
988 *isExpanded = false;
989 *isExpandable = false;
991 if( !m_xAccContextRef.is() )
993 return;
995 sal_Int64 nRState = m_xAccContextRef->getAccessibleStateSet();
997 if (nRState & EXPANDED)
998 *isExpanded = true;
999 if (nRState & EXPANDABLE)
1000 *isExpandable = true;
1003 void AccObject::NotifyDestroy()
1005 if(m_pIMAcc)
1006 m_pIMAcc->NotifyDestroy();
1009 void AccObject::SetParentObj(AccObject* pParentAccObj)
1011 m_pParentObj = pParentAccObj;
1013 if(m_pIMAcc)
1015 if(m_pParentObj)
1017 m_pIMAcc->Put_XAccParent(m_pParentObj->GetIMAccessible());
1019 else
1021 m_pIMAcc->Put_XAccParent(nullptr);
1025 //ResID means ChildID in MSAA
1026 void AccObject::SetResID(long id)
1028 m_resID = id;
1029 if(m_pIMAcc)
1030 m_pIMAcc->Put_XAccChildID(m_resID);
1032 //return COM interface in acc object
1033 IMAccessible* AccObject::GetIMAccessible()
1035 return m_pIMAcc;
1038 Reference<XAccessible> const& AccObject::GetXAccessible()
1040 return m_xAccRef;
1043 void AccObject::SetParentHWND(HWND hWnd)
1045 m_pParantID = hWnd;
1048 rtl::Reference<AccEventListener> AccObject::SetListener(rtl::Reference<AccEventListener> const& pListener)
1050 rtl::Reference<AccEventListener> pRet(m_pListener);
1051 m_pListener = pListener;
1052 return pRet;
1055 AccEventListener* AccObject::getListener()
1057 return m_pListener.get();
1060 long AccObject::GetResID()
1062 return m_resID;
1065 HWND AccObject::GetParentHWND()
1067 return m_pParantID;
1070 AccObject* AccObject::GetParentObj()
1072 return m_pParentObj;
1075 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */