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