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