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