1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright IBM Corporation 2010.
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org.  If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 #include <com/sun/star/uno/Sequence.h>
30 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
31 #include <com/sun/star/accessibility/AccessibleRole.hpp>
32 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
33 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
34 #include <com/sun/star/accessibility/XAccessibleText.hpp>
35 
36 #include <stdlib.h>
37 #include <memory.h>
38 #include <stdio.h>
39 #include <memory.h>
40 #include <algorithm>
41 #include <assert.h>
42 
43 #include "AccObject.hxx"
44 #include "AccEventListener.hxx"
45 #include "UAccCOM_i.c"
46 #include "AccResource.hxx"
47 #include "AccessibleRole.h"
48 
49 
50 
51 
52 using namespace std;
53 using namespace com::sun::star::uno;
54 using namespace com::sun::star::accessibility;
55 using namespace com::sun::star::accessibility::AccessibleRole;
56 using namespace com::sun::star::accessibility::AccessibleStateType;
57 
58 
59 /**
60    * Constructor.
61    * @param pXAcc Uno XAccessible interface of control.
62    * @param Agent The agent kept in all listeners,it's the sole interface by which
63    *              listener communicate with windows manager.
64    * @param listener listener that registers in UNO system.
65    * @return.
66    */
67 AccObject::AccObject(XAccessible* pAcc,AccObjectManagerAgent* pAgent ,AccEventListener* listener) :
68         m_pIMAcc	(NULL),
69         m_resID		(NULL),
70         m_pParantID	(NULL),
71         m_pParentObj(NULL),
72         m_accListener (listener),
73         m_bShouldDestroy(sal_False),
74         m_xAccRef( pAcc )
75 {
76     sal_Bool bRet = ImplInitilizeCreateObj();
77 
78     m_xAccContextRef = m_xAccRef->getAccessibleContext();
79     m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
80     m_accRole = m_xAccContextRef -> getAccessibleRole();
81     if( m_pIMAcc )
82     {
83         m_pIMAcc->SetXAccessible((long) m_xAccRef.get());
84         m_pIMAcc->Put_XAccAgent((long)pAgent);
85         m_pIMAcc->SetDefaultAction((long)m_xAccActionRef.get());
86     }
87 }
88 /**
89    * Destructor.
90    * @param
91    * @return
92    */
93 AccObject::~AccObject()
94 {
95     m_pIMAcc = NULL;
96     m_xAccRef = NULL;
97     m_xAccActionRef = NULL;
98     m_xAccContextRef = NULL;
99 }
100 
101 
102 
103 /**
104    * Insert a child element.
105    * @param pChild Child element that should be inserted into child list.
106    * @param pos Insert postion.
107    * @return
108    */
109 void AccObject::InsertChild( AccObject* pChild,short pos )
110 {
111 
112     std::vector<AccObject*>::iterator iter;
113     iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
114     if(iter!=m_childrenList.end())
115         return;
116     if(LAST_CHILD==pos)
117     {
118         m_childrenList.push_back(pChild);
119     }
120     else
121     {
122         std::vector<AccObject*>::iterator iter=m_childrenList.begin()+pos;
123         m_childrenList.insert(iter,pChild);
124     }
125 
126     pChild->SetParentObj(this);
127 }
128 
129 /**
130    * Delete a child element
131    * @param pChild Child element that should be inserted into child list.
132    * @param pos Insert postion.
133    * @return
134    */
135 void AccObject::DeleteChild( AccObject* pChild )
136 {
137     std::vector<AccObject*>::iterator iter;
138     iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
139     if(iter!=m_childrenList.end())
140     {
141         m_childrenList.erase(iter);
142         if(m_pIMAcc)
143             pChild->SetParentObj(NULL);
144     }
145 }
146 
147 /**
148    * In order to windows API WindowFromAccessibleObject,we sometimes to set a pure
149    * top window accessible object created by windows system as top ancestor.
150    * @param.
151    * @return
152    */
153 void AccObject::UpdateValidWindow()
154 {
155     if(m_pIMAcc)
156         m_pIMAcc->Put_XAccWindowHandle(m_pParantID);
157 }
158 
159 /**
160    * Translate all UNO basic information into MSAA com information.
161    * @param
162    * @return If the method is correctly processed.
163    */
164 sal_Bool AccObject::ImplInitilizeCreateObj()
165 {
166 
167     if ( S_OK != CoCreateInstance( CLSID_MAccessible, NULL, CLSCTX_ALL ,
168                                    IID_IMAccessible,
169                                    (void **)&m_pIMAcc
170                                  )
171        )
172     {
173         return sal_False;
174     }
175 
176     return sal_True;
177 }
178 
179 /**
180    * Update name property to com object.
181    * @param
182    * @return
183    */
184 void  AccObject::UpdateName( )
185 {
186     if (!m_pIMAcc)
187     {
188         return;
189     }
190 
191     if( ( TEXT_FRAME == m_accRole   ) && ( m_pParentObj !=NULL )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) )
192         m_pIMAcc->Put_XAccName( m_pParentObj->m_xAccContextRef->getAccessibleName().getStr() );
193 	//IAccessibility2 Implementation 2009-----
194     if ( PARAGRAPH == m_accRole)
195     {
196     	::rtl::OUString emptyStr = ::rtl::OUString::createFromAscii("");
197     	m_pIMAcc->Put_XAccName(emptyStr.getStr());
198     }
199 	//-----IAccessibility2 Implementation 2009
200     else
201         m_pIMAcc->Put_XAccName(m_xAccContextRef->getAccessibleName().getStr());
202 
203     return ;
204 }
205 /**
206    * Update description property to com object.
207    * no content for update description
208    * @param
209    * @return
210    */
211 void AccObject::UpdateDescription()
212 {
213     if (!m_pIMAcc)
214     {
215         return;
216     }
217 
218     m_pIMAcc->Put_XAccDescription(m_xAccContextRef->getAccessibleDescription().getStr());
219     return ;
220 }
221 
222 /**
223    * Update default action property to com object.
224    * @param
225    * @return
226    */
227 void  AccObject::UpdateAction()
228 {
229     m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
230 
231     if( m_xAccActionRef.is() && m_pIMAcc )
232     {
233         if( m_xAccActionRef->getAccessibleActionCount() > 0 )
234         {
235             UpdateDefaultAction( );
236             m_pIMAcc->SetDefaultAction((long)m_xAccActionRef.get());
237         }
238     }
239 }
240 
241 /**
242    * Update value property to com object.
243    * @param
244    * @return
245    */
246 void AccObject::UpdateValue()
247 {
248     if( NULL == m_pIMAcc  || !m_xAccContextRef.is() )
249     {
250         assert(false);
251         return ;
252     }
253 
254     Reference< XAccessibleValue > pRValue(m_xAccContextRef.get(),UNO_QUERY);
255     Any pAny;
256     if( pRValue.is() )
257     {
258         pAny = pRValue->getCurrentValue();
259     }
260 
261     SetValue( pAny );
262 }
263 
264 /**
265    * Set special default action description string via UNO role.
266    * @param Role UNO role
267    * @return
268    */
269 void AccObject::UpdateDefaultAction( )
270 {
271     if(!m_xAccActionRef.is())
272         return ;
273 
274     switch(m_accRole)
275     {
276     case PUSH_BUTTON:
277     case TOGGLE_BUTTON:
278     case RADIO_BUTTON:
279     case MENU_ITEM:
280     case RADIO_MENU_ITEM:
281     case CHECK_MENU_ITEM:
282     case LIST_ITEM:
283     case CHECK_BOX:
284     case TREE_ITEM:
285     case BUTTON_DROPDOWN:
286         m_pIMAcc->Put_ActionDescription( m_xAccActionRef->getAccessibleActionDescription((sal_Int32)0).getStr() );
287         return;
288     }
289 }
290 
291 /**
292    * Set value property via pAny.
293    * @param pAny New value.
294    * @return
295    */
296 void  AccObject::SetValue( Any pAny )
297 {
298     unsigned short pUNumberString[100];
299     memset( pUNumberString, 0 , sizeof( pUNumberString) );
300 
301     if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
302     {
303         assert(false);
304         return ;
305     }
306     Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY);
307     ::rtl::OUString val;
308     int index = 0 ;
309     switch(m_accRole)
310     {
311     case SPIN_BOX:
312         // 3. date editor's msaa value should be the same as spinbox
313     case DATE_EDITOR:
314     case TEXT:
315     case PARAGRAPH:
316     case HEADING:
317 
318         if(pRText.get())
319         {
320             val = pRText->getText();
321         }
322         m_pIMAcc->Put_XAccValue( val.getStr() );
323         break;
324     case TREE_ITEM:
325 	//IAccessibility2 Implementation 2009-----
326     //case CHECK_BOX:	//Commented by Li Xing to disable the value for general checkbox
327     case COMBO_BOX:
328     case TABLE_CELL:
329     case NOTE:
330     case SCROLL_BAR:
331         m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
332         break ;
333 	// Added by Li Xing, only the checkbox in tree should have the value.
334 	case CHECK_BOX:
335 		if( ( m_pParentObj !=NULL ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole ))
336 	        m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
337 	//-----IAccessibility2 Implementation 2009
338 		break;
339     default:
340         break;
341     }
342 
343     return;
344 
345 
346 }
347 ::rtl::OUString AccObject::GetMAccessibleValueFromAny(Any pAny)
348 {
349     ::rtl::OUString strValue;
350 
351     if(NULL == m_pIMAcc)
352         return strValue;
353 
354     if(pAny.getValueType() == getCppuType( (sal_uInt16 *)0 ) )
355     {
356         sal_uInt16 val;
357         if (pAny >>= val)
358         {
359             strValue=::rtl::OUString::valueOf((sal_Int32)val);
360 
361         }
362     }
363     else if(pAny.getValueType() == getCppuType( (::rtl::OUString *)0 ) )
364     {
365 
366         pAny >>= strValue ;
367 
368     }
369     else if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) )
370     {
371         Sequence< ::rtl::OUString > val;
372         if (pAny >>= val)
373         {
374 
375             int count = val.getLength();
376 
377             for( int iIndex = 0;iIndex < count;iIndex++ )
378             {
379                 strValue += val[iIndex];
380             }
381 
382         }
383     }
384     else if(pAny.getValueType() == getCppuType( (double *)0 ) )
385     {
386         double val;
387         if (pAny >>= val)
388         {
389             strValue=::rtl::OUString::valueOf(val);
390         }
391     }
392     else if(pAny.getValueType() == getCppuType( (sal_Int32 *)0 ) )
393     {
394         sal_Int32 val;
395         if (pAny >>= val)
396         {
397             strValue=::rtl::OUString::valueOf(val);
398         }
399     }
400     else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) )
401     {
402         com::sun::star::accessibility::TextSegment val;
403         if (pAny >>= val)
404         {
405             ::rtl::OUString realVal(val.SegmentText);
406             strValue = realVal;
407 
408         }
409     }
410 
411     return strValue;
412 }
413 /**
414    * Set name property via pAny.
415    * @param pAny New accessible name.
416    * @return
417    */
418 void  AccObject::SetName( Any pAny)
419 {
420     if( NULL == m_pIMAcc )
421         return ;
422 
423     m_pIMAcc->Put_XAccName( GetMAccessibleValueFromAny(pAny).getStr() );
424 
425 }
426 
427 /**
428    * Set description property via pAny.
429    * @param pAny New accessible description.
430    * @return
431    */
432 void  AccObject::SetDescription( Any pAny )
433 {
434     if( NULL == m_pIMAcc )
435         return ;
436     m_pIMAcc->Put_XAccDescription( GetMAccessibleValueFromAny(pAny).getStr() );
437 }
438 
439 /**
440    * Set role property via pAny
441    * @param Role New accessible role.
442    * @return
443    */
444 void  AccObject::SetRole( short Role )
445 {
446     if( NULL == m_pIMAcc )
447         return ;
448     m_pIMAcc->Put_XAccRole( Role );
449 }
450 
451 /**
452 * Get role property via pAny
453 * @param
454 * @return accessible role
455 */
456 short AccObject::GetRole() const
457 {
458     return m_accRole;
459 }
460 
461 /**
462    * Get MSAA state from UNO state
463    * @Role xState UNO state.
464    * @return
465    */
466 DWORD AccObject::GetMSAAStateFromUNO(short xState)
467 {
468     DWORD IState = UNO_MSAA_UNMAPPING;
469 
470     if( !m_xAccContextRef.is() )
471     {
472         assert(false);
473         return IState;
474     }
475     short Role = m_accRole;
476 
477     switch( xState )
478     {
479     case  BUSY:
480         IState = STATE_SYSTEM_BUSY;
481         break;
482     case  CHECKED:
483         if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON )
484         {
485             IState = STATE_SYSTEM_PRESSED;
486         }
487         else
488             IState = STATE_SYSTEM_CHECKED;
489         break;
490     case  DEFUNC:
491         IState = STATE_SYSTEM_UNAVAILABLE;
492         break;
493     case  EXPANDED:
494         IState = STATE_SYSTEM_EXPANDED;
495         break;
496     case  FOCUSABLE:
497         IState = STATE_SYSTEM_FOCUSABLE;
498         break;
499     case  FOCUSED:
500         IState = STATE_SYSTEM_FOCUSED;
501         break;
502     case  INDETERMINATE:
503         IState = STATE_SYSTEM_MIXED;
504         break;
505     case  MULTI_SELECTABLE:
506         IState = STATE_SYSTEM_MULTISELECTABLE;
507         break;
508     case  PRESSED:
509         IState = STATE_SYSTEM_PRESSED;
510         break;
511     case  RESIZABLE:
512         IState = STATE_SYSTEM_SIZEABLE;
513         break;
514     case  SELECTABLE:
515         if( m_accRole == MENU || m_accRole == MENU_ITEM)
516         {
517             IState = UNO_MSAA_UNMAPPING;
518         }
519         else
520         {
521             IState = STATE_SYSTEM_SELECTABLE;
522         }
523         break;
524     case  SELECTED:
525         if( m_accRole == MENU || m_accRole == MENU_ITEM )
526         {
527             IState = UNO_MSAA_UNMAPPING;
528         }
529         else
530         {
531             IState = STATE_SYSTEM_SELECTED;
532         }
533         break;
534     case  ARMED:
535         IState = STATE_SYSTEM_FOCUSED;
536         break;
537     case  EXPANDABLE:
538         {
539             sal_Bool isExpanded = sal_True;
540             sal_Bool isExpandable = sal_True;
541             if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON  || BUTTON_DROPDOWN == Role )
542             {
543                 IState = STATE_SYSTEM_HASPOPUP;
544             }
545             else
546             {
547                 GetExpandedState(&isExpandable,&isExpanded);
548                 if(!isExpanded)
549                     IState = STATE_SYSTEM_COLLAPSED;
550             }
551         }
552         break;
553 	//Remove the SENSITIVE state mapping. There is no corresponding MSAA state.
554     //case  SENSITIVE:
555     //    IState = STATE_SYSTEM_PROTECTED;
556     case EDITABLE:
557         if( m_pIMAcc )
558         {
559             m_pIMAcc->DecreaseState( STATE_SYSTEM_READONLY );
560         }
561         break;
562     case OFFSCREEN:
563         IState = STATE_SYSTEM_OFFSCREEN;
564         break;
565     case MOVEABLE:
566         IState = STATE_SYSTEM_MOVEABLE;
567         break;
568     case COLLAPSE:
569         IState = STATE_SYSTEM_COLLAPSED;
570         break;
571     case DEFAULT:
572         IState = STATE_SYSTEM_DEFAULT;
573         break;
574     default:
575         break;
576     }
577 
578     return IState;
579 }
580 
581 /**
582    * Decrease state of com object
583    * @param xState The lost state.
584    * @return
585    */
586 void  AccObject::DecreaseState( short xState )
587 {
588     if( NULL == m_pIMAcc )
589     {
590         return;
591     }
592 
593     if( xState == FOCUSABLE)
594     {
595         short Role = m_accRole ;
596         if(Role == MENU_ITEM
597                 || Role == RADIO_MENU_ITEM
598                 || Role == CHECK_MENU_ITEM)
599             return;
600         else
601         {
602             if (Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
603             {
604                 if( ( m_pParentObj !=NULL ) && (TOOL_BAR == m_pParentObj->m_accRole ) )
605                     return;
606             }
607         }
608     }
609 
610     else if( xState == AccessibleStateType::VISIBLE  )
611     {
612         m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
613     }
614     else if( xState == AccessibleStateType::SHOWING )
615     {
616         m_pIMAcc->IncreaseState( STATE_SYSTEM_OFFSCREEN );
617     }
618 
619     DWORD msState = GetMSAAStateFromUNO(xState);
620     if(msState!=UNO_MSAA_UNMAPPING)
621         m_pIMAcc->DecreaseState(msState);
622 }
623 
624 /**
625    * Increase state of com object
626    * @param xState The new state.
627    * @return
628    */
629 void AccObject::IncreaseState( short xState )
630 {
631     if( NULL == m_pIMAcc )
632     {
633         assert(false);
634         return;
635     }
636 
637 
638     if( xState == AccessibleStateType::VISIBLE  )
639     {
640         m_pIMAcc->DecreaseState( STATE_SYSTEM_INVISIBLE );
641     }
642     else if( xState == AccessibleStateType::SHOWING )
643     {
644         m_pIMAcc->DecreaseState( STATE_SYSTEM_OFFSCREEN );
645     }
646 
647 
648     DWORD msState = GetMSAAStateFromUNO(xState);
649     if(msState!=UNO_MSAA_UNMAPPING)
650         m_pIMAcc->IncreaseState( msState );
651 }
652 
653 /**
654    * Get next child element
655    * @param
656    * @return AccObject Object interface.
657    */
658 AccObject* AccObject::NextChild()
659 {
660     IAccChildList::iterator pInd = m_childrenList.begin();
661     if( pInd != m_childrenList.end() )
662         return 	*pInd;
663     return NULL;
664 }
665 /**
666    * update action desciption desc
667    * @param
668    * @return
669    */
670 void AccObject::UpdateActionDesc()
671 {
672     if (!m_pIMAcc)
673     {
674         return;
675     }
676 
677     ::rtl::OUString	pXString = m_xAccContextRef->getAccessibleDescription();
678     m_pIMAcc->Put_XAccDescription(pXString.getStr());
679     long Role = m_accRole;
680 
681     if(  Role == PUSH_BUTTON || Role == RADIO_BUTTON || Role == MENU_ITEM ||
682             Role == LIST_ITEM || Role == CHECK_BOX || Role == TREE_ITEM ||
683             Role == CHECK_MENU_ITEM || Role == RADIO_MENU_ITEM )
684     {
685         UpdateDefaultAction(  );
686     }
687     else
688     {
689 
690         if( m_xAccActionRef.is() )
691         {
692             if( m_xAccActionRef->getAccessibleActionCount() > 0 )
693             {
694 				if (!(Role == SPIN_BOX || Role == COMBO_BOX || Role == DATE_EDITOR ||
695 					  Role == EDIT_BAR || Role == PASSWORD_TEXT || Role == TEXT))
696 				{
697 					pXString = m_xAccActionRef->getAccessibleActionDescription( 0 );
698 					//Solution:If string length is more than zero,action will will be set.
699 					if( pXString.getLength() > 0)
700 						m_pIMAcc->Put_ActionDescription( pXString.getStr() );
701 				}
702             }
703         }
704     }
705 
706 }
707 /**
708    * update role information from uno to com
709    * @param
710    * @return
711    */
712 void AccObject::UpdateRole()
713 {
714     if (!m_pIMAcc)
715     {
716         return;
717     }
718 
719     XAccessibleContext* pContext  = m_xAccContextRef.get();
720     m_pIMAcc->Put_XAccRole( ROLE_SYSTEM_WINDOW  );
721     short iRoleIndex = pContext->getAccessibleRole();
722     if (( 0 <= iRoleIndex) && ( iRoleIndex <= (sizeof(ROLE_TABLE)/(sizeof(short)*2))))
723     {
724         short iIA2Role = ROLE_TABLE[iRoleIndex][1] ;
725         m_pIMAcc->Put_XAccRole( iIA2Role  );
726     }
727 
728 }
729 /**
730    * update state information from uno to com
731    * @param
732    * @return
733    */
734 void AccObject::UpdateState()
735 {
736     if (!m_pIMAcc)
737     {
738         return;
739     }
740 
741     XAccessibleContext* pContext  = m_xAccContextRef.get();
742     Reference< XAccessibleStateSet > pRState = pContext->getAccessibleStateSet();
743     if( !pRState.is() )
744     {
745         assert(false);
746         return ;
747     }
748 
749     m_pIMAcc->SetState(0L);
750 
751     if ( m_accRole == POPUP_MENU )
752     {
753         return;
754     }
755 
756     Sequence<short> pStates = pRState->getStates();
757     int count = pStates.getLength();
758 
759     sal_Bool isEnable = sal_False;
760     sal_Bool isShowing = sal_False;
761     sal_Bool isEditable = sal_False;
762     sal_Bool isVisible = sal_False;
763     sal_Bool isFocusable = sal_False;
764 
765     for( int iIndex = 0;iIndex < count;iIndex++ )
766     {
767         if( pStates[iIndex] == ENABLED )
768             isEnable = sal_True;
769         else if( pStates[iIndex] == SHOWING)
770             isShowing = sal_True;
771         else if( pStates[iIndex] == VISIBLE)
772             isVisible = sal_True;
773         else if( pStates[iIndex] == EDITABLE )
774             isEditable = sal_True;
775         else if (pStates[iIndex] == FOCUSABLE)
776             isFocusable = sal_True;
777         IncreaseState( pStates[iIndex]);
778     }
779     sal_Bool bIsMenuItem = m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM;
780 
781     if(bIsMenuItem)
782     {
783         if(!(isShowing && isVisible) )
784         {
785             m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
786             m_pIMAcc->DecreaseState( STATE_SYSTEM_FOCUSABLE );
787         }
788     }
789     else
790     {
791         if(!(isShowing || isVisible) )
792             m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
793     }
794 
795     short Role = m_accRole;
796 
797     if( m_pIMAcc )
798     {
799         switch(m_accRole)
800         {
801         case LABEL:
802             m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
803             break;
804         case TEXT:
805             // 2. editable combobox -> readonly ------ bridge
806         case EMBEDDED_OBJECT:
807         case END_NOTE:
808         case FOOTER:
809         case FOOTNOTE:
810         case GRAPHIC:
811         case HEADER:
812         case HEADING:
813 
814             //Image Map
815         case PARAGRAPH:
816         case PASSWORD_TEXT:
817         case SHAPE:
818         case SPIN_BOX:
819         case TABLE:
820         case TABLE_CELL:
821         case TEXT_FRAME:
822         case DATE_EDITOR:
823         case DOCUMENT:
824         case COLUMN_HEADER:
825             {
826                 if(!isEditable)
827                     m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
828             }
829             break;
830         default:
831             break;
832         }
833     }
834 
835     if( isEnable )
836     {
837 
838         if(!(Role == FILLER || Role == END_NOTE || Role == FOOTER || Role == FOOTNOTE || Role == GROUP_BOX || Role == RULER
839                 || Role == HEADER || Role == ICON || Role == INTERNAL_FRAME || Role == LABEL || Role == LAYERED_PANE
840                 || Role == SCROLL_BAR || Role == SCROLL_PANE || Role == SPLIT_PANE || Role == STATUS_BAR || Role == TOOL_TIP))
841         {
842             if( SEPARATOR == Role  )
843             {
844                 if( ( m_pParentObj != NULL ) && ( MENU == m_pParentObj->m_accRole  || POPUP_MENU == m_pParentObj->m_accRole ))
845                     IncreaseState( FOCUSABLE );
846             }
847 
848             else if (TABLE_CELL == Role || TABLE == Role || PANEL == Role || OPTION_PANE == Role ||
849                      COLUMN_HEADER == Role)
850             {
851                 if (isFocusable)
852                     IncreaseState( FOCUSABLE );
853             }
854             else
855             {
856                 if(bIsMenuItem)
857                 {
858                     if ( isShowing && isVisible)
859                     {
860                         IncreaseState( FOCUSABLE );
861                     }
862                 }
863                 else
864                 {
865                     IncreaseState( FOCUSABLE );
866                 }
867             }
868         }
869     }
870     else
871     {
872         m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE );
873         sal_Bool isDecreaseFocusable = sal_False;
874         if( !((Role == MENU_ITEM) ||
875                 (Role == RADIO_MENU_ITEM) ||
876                 (Role == CHECK_MENU_ITEM)) )
877         {
878             if  ( Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
879             {
880                 if(( m_pParentObj != NULL )&& (TOOL_BAR ==  m_pParentObj->m_accRole ) )
881                     IncreaseState( FOCUSABLE );
882                 else
883                     DecreaseState( FOCUSABLE );
884             }
885             else
886                 DecreaseState( FOCUSABLE );
887         }
888         else if( isShowing || isVisible )
889         {
890             IncreaseState( FOCUSABLE );
891         }
892     }
893 
894     if( m_pIMAcc )
895     {
896         switch(m_accRole)
897         {
898         case POPUP_MENU:
899         case MENU:
900             if( pContext->getAccessibleChildCount() > 0 )
901                 m_pIMAcc->IncreaseState( STATE_SYSTEM_HASPOPUP );
902             break;
903         case PASSWORD_TEXT:
904             m_pIMAcc->IncreaseState( STATE_SYSTEM_PROTECTED );
905             break;
906         default:
907             break;
908         }
909     }
910 
911 }
912 /**
913    * update location information from uno to com
914    * @param
915    * @return
916    */
917 void AccObject::UpdateLocation()
918 {
919     if (!m_pIMAcc)
920     {
921         return;
922     }
923     XAccessibleContext* pContext  = m_xAccContextRef.get();
924 
925     Reference< XAccessibleComponent > pRComponent(pContext,UNO_QUERY);
926     if( pRComponent.is() )
927     {
928         ::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen();
929         ::com::sun::star::awt::Size pCSize = pRComponent->getSize();
930         Location tempLocation;
931         tempLocation.m_dLeft = pCPoint.X;
932         tempLocation.m_dTop =  pCPoint.Y;
933         tempLocation.m_dWidth = pCSize.Width;
934         tempLocation.m_dHeight = pCSize.Height;
935         m_pIMAcc->Put_XAccLocation( tempLocation );
936     }
937 
938 }
939 
940 
941 /**
942    * Public method to mapping information between MSAA and UNO.
943    * @param
944    * @return If the method is correctly processed.
945    */
946 sal_Bool AccObject:: UpdateAccessibleInfoFromUnoToMSAA ( )
947 {
948     if( NULL == m_pIMAcc || !m_xAccContextRef.is()  )
949     {
950         assert(false);
951         return sal_False;
952     }
953 
954     UpdateName();
955 
956     UpdateValue();
957 
958     UpdateActionDesc();
959 
960     UpdateRole();
961 
962     UpdateLocation();
963 
964     UpdateState();
965 
966     return sal_True;
967 }
968 
969 /*
970    * Add a child selected element.
971    * @param pAccObj Child object pointer.
972    * @return
973    */
974 void AccObject::AddSelect( long index, AccObject* accObj)
975 {
976     m_selectionList.insert(IAccSelectionList::value_type(index,accObj));
977 }
978 
979 IAccSelectionList& AccObject::GetSelection()
980 {
981     return m_selectionList;
982 }
983 
984 
985 /**
986    * Set self to focus object in parant child list
987    * @param
988    * @return
989    */
990 void AccObject::setFocus()
991 {
992     if(m_pIMAcc)
993     {
994         IncreaseState(FOCUSED);
995         m_pIMAcc->Put_XAccFocus(CHILDID_SELF);
996 
997         UpdateRole();
998     }
999 }
1000 
1001 /**
1002    * Unset self from focus object in parant child list.
1003    * @param
1004    * @return
1005    */
1006 void AccObject::unsetFocus()
1007 {
1008     if(m_pIMAcc)
1009     {
1010         DecreaseState( FOCUSED );
1011         m_pIMAcc->Put_XAccFocus(UACC_NO_FOCUS);
1012     }
1013 }
1014 
1015 void AccObject::GetExpandedState( sal_Bool* isExpandable, sal_Bool* isExpanded)
1016 {
1017     *isExpanded = sal_False;
1018     *isExpandable = sal_False;
1019 
1020     if( !m_xAccContextRef.is() )
1021     {
1022         return;
1023     }
1024     Reference< XAccessibleStateSet > pRState = m_xAccContextRef->getAccessibleStateSet();
1025     if( !pRState.is() )
1026     {
1027         return;
1028     }
1029 
1030     Sequence<short> pStates = pRState->getStates();
1031     int count = pStates.getLength();
1032 
1033     for( int iIndex = 0;iIndex < count;iIndex++ )
1034     {
1035         if( EXPANDED == pStates[iIndex]  )
1036         {
1037             *isExpanded = sal_True;
1038         }
1039         else if( EXPANDABLE == pStates[iIndex]  )
1040         {
1041             *isExpandable = sal_True;
1042         }
1043     }
1044 }
1045 
1046 void AccObject::NotifyDestroy(sal_Bool ifDelete)
1047 {
1048     m_bShouldDestroy=ifDelete;
1049     if(m_pIMAcc)
1050         m_pIMAcc->NotifyDestroy(m_bShouldDestroy);
1051 }
1052 
1053 void AccObject::SetParentObj(AccObject* pParentAccObj)
1054 {
1055     m_pParentObj = pParentAccObj;
1056 
1057     if(m_pIMAcc)
1058     {
1059         if(m_pParentObj)
1060         {
1061             m_pIMAcc->Put_XAccParent(m_pParentObj->GetIMAccessible());
1062         }
1063         else
1064         {
1065             m_pIMAcc->Put_XAccParent(NULL);
1066         }
1067     }
1068 }
1069 //ResID means ChildID in MSAA
1070 void AccObject::SetResID(long id)
1071 {
1072     m_resID = id;
1073     if(m_pIMAcc)
1074         m_pIMAcc->Put_XAccChildID(m_resID);
1075 }
1076 //return COM interface in acc object
1077 IMAccessible*  AccObject::GetIMAccessible()
1078 {
1079     return m_pIMAcc;
1080 }
1081 
1082 Reference < XAccessible > AccObject::GetXAccessible()
1083 {
1084     return m_xAccRef;
1085 }
1086 
1087 void AccObject::SetParentHWND(HWND hWnd)
1088 {
1089     m_pParantID = hWnd;
1090 }
1091 void AccObject::SetListener( AccEventListener* Listener )
1092 {
1093     m_accListener = Listener;
1094 }
1095 AccEventListener* AccObject::getListener()
1096 {
1097     return m_accListener;
1098 }
1099 
1100 long AccObject::GetResID()
1101 {
1102     return m_resID;
1103 }
1104 
1105 HWND AccObject::GetParentHWND()
1106 {
1107     return m_pParantID;
1108 }
1109 
1110 AccObject* AccObject::GetParentObj()
1111 {
1112     return m_pParentObj;
1113 }
1114 sal_Bool  AccObject::ifShouldDestroy()
1115 {
1116     return m_bShouldDestroy;
1117 }
1118