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 ////////////////////////////////////////////////////////////////////// 23 // AccActionBase.cpp: implementation of the CAccActionBase class. 24 ////////////////////////////////////////////////////////////////////// 25 #include "stdafx.h" 26 27 #include "AccActionBase.h" 28 #include <com/sun/star/accessibility/XAccessible.hpp> 29 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 30 #include <com/sun/star/accessibility/AccessibleRole.hpp> 31 #include <com/sun/star/accessibility/XAccessibleContext.hpp> 32 33 #include "AccessibleKeyStroke.h" 34 35 #ifndef __ACCCOMMON_H_ 36 #include "acccommon.h" 37 #endif 38 39 using namespace com::sun::star::accessibility::AccessibleRole; 40 using namespace com::sun::star::accessibility; 41 using namespace com::sun::star::uno; 42 using namespace com::sun::star::awt; 43 44 ////////////////////////////////////////////////////////////////////// 45 // Construction/Destruction 46 ////////////////////////////////////////////////////////////////////// 47 48 CAccActionBase::CAccActionBase() 49 {} 50 51 CAccActionBase::~CAccActionBase() 52 {} 53 54 /** 55 * Helper function used for getting default action by UNO role. 56 * 57 * @param pRContext UNO context interface pointer. 58 * @param pRet the corresponding string to be returned. 59 */ 60 void GetDfActionByUNORole(XAccessibleContext* pRContext, BSTR* pRet) 61 { 62 // #CHECK# 63 if(pRContext == NULL || pRet == NULL) 64 { 65 return; 66 } 67 68 long Role = pRContext->getAccessibleRole(); 69 70 switch(Role) 71 { 72 case PUSH_BUTTON: 73 *pRet = ::SysAllocString(PRESS); 74 break; 75 case RADIO_BUTTON: 76 case MENU_ITEM: 77 case LIST_ITEM: 78 *pRet = ::SysAllocString(SELECT); 79 break; 80 case CHECK_BOX: 81 { 82 Reference< XAccessibleStateSet > pRState = pRContext->getAccessibleStateSet(); 83 if( !pRState.is() ) 84 { 85 return; 86 } 87 88 Sequence<short> pStates = pRState->getStates(); 89 int count = pStates.getLength(); 90 *pRet = ::SysAllocString(CHECK); 91 for( int iIndex = 0;iIndex < count;iIndex++ ) 92 { 93 if( pStates[iIndex] == AccessibleStateType::CHECKED ) 94 { 95 SAFE_SYSFREESTRING(*pRet); 96 *pRet = ::SysAllocString(UNCHECK); 97 break; 98 } 99 } 100 break; 101 } 102 } 103 } 104 105 /** 106 * Returns the number of action. 107 * 108 * @param nActions the number of action. 109 */ 110 STDMETHODIMP CAccActionBase::nActions(/*[out,retval]*/long* nActions) 111 { 112 113 CHECK_ENABLE_INF 114 115 ENTER_PROTECTED_BLOCK 116 117 // #CHECK# 118 if( pRXAct.is() && nActions != NULL ) 119 { 120 *nActions = GetXInterface()->getAccessibleActionCount(); 121 return S_OK; 122 } 123 *nActions = 0; 124 125 return S_OK; 126 127 LEAVE_PROTECTED_BLOCK 128 } 129 130 /** 131 * Performs specified action on the object. 132 * 133 * @param actionIndex the index of action. 134 */ 135 STDMETHODIMP CAccActionBase::doAction(/* [in] */ long actionIndex) 136 { 137 138 CHECK_ENABLE_INF 139 140 ENTER_PROTECTED_BLOCK 141 142 if( pRXAct.is() ) 143 { 144 return GetXInterface()->doAccessibleAction( actionIndex )?S_OK:E_FAIL; 145 } 146 return E_FAIL; 147 148 LEAVE_PROTECTED_BLOCK 149 } 150 151 /** 152 * Gets description of specified action. 153 * 154 * @param actionIndex the index of action. 155 * @param description the description string of the specified action. 156 */ 157 STDMETHODIMP CAccActionBase::get_description(long actionIndex,BSTR __RPC_FAR *description) 158 { 159 160 CHECK_ENABLE_INF 161 162 ENTER_PROTECTED_BLOCK 163 164 // #CHECK# 165 if(description == NULL) 166 return E_INVALIDARG; 167 168 // #CHECK XInterface# 169 if(!pRXAct.is()) 170 return E_FAIL; 171 172 ::rtl::OUString ouStr = GetXInterface()->getAccessibleActionDescription(actionIndex); 173 // #CHECK# 174 175 SAFE_SYSFREESTRING(*description); 176 *description = SysAllocString((OLECHAR*)ouStr.getStr()); 177 178 return S_OK; 179 180 LEAVE_PROTECTED_BLOCK 181 } 182 183 STDMETHODIMP CAccActionBase::get_name( long, BSTR __RPC_FAR *) 184 { 185 return E_NOTIMPL; 186 } 187 188 STDMETHODIMP CAccActionBase::get_localizedName( long, BSTR __RPC_FAR *) 189 { 190 return E_NOTIMPL; 191 } 192 193 /** 194 * Returns key binding object (if any) associated with specified action 195 * key binding is string. 196 * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). 197 * 198 * @param actionIndex the index of action. 199 * @param nMaxBinding the max number of key binding. 200 * @param keyBinding the key binding array. 201 * @param nBinding the actual number of key binding returned. 202 */ 203 STDMETHODIMP CAccActionBase::get_keyBinding( 204 /* [in] */ long actionIndex, 205 /* [in] */ long, 206 /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, 207 /* [retval][out] */ long __RPC_FAR *nBinding) 208 { 209 210 CHECK_ENABLE_INF 211 212 ENTER_PROTECTED_BLOCK 213 214 if( !keyBinding || !nBinding) 215 return E_INVALIDARG; 216 217 if( !pRXAct.is() ) 218 return E_FAIL; 219 220 Reference< XAccessibleKeyBinding > binding = GetXInterface()->getAccessibleActionKeyBinding(actionIndex); 221 if( !binding.is() ) 222 return E_FAIL; 223 224 long nCount = (binding.get())->getAccessibleKeyBindingCount(); 225 226 OLECHAR wString[64]; 227 228 *keyBinding = (BSTR*)::CoTaskMemAlloc(nCount*sizeof(BSTR)); 229 230 // #CHECK Memory Allocation# 231 if(*keyBinding == NULL) 232 return E_FAIL; 233 234 for( int index = 0;index < nCount;index++ ) 235 { 236 memset(wString,0,sizeof(wString)); 237 GetkeyBindingStrByXkeyBinding( (binding.get())->getAccessibleKeyBinding(index), wString ); 238 239 (*keyBinding)[index] = SysAllocString(wString); 240 } 241 242 *nBinding = nCount; 243 return S_OK; 244 245 LEAVE_PROTECTED_BLOCK 246 } 247 248 /** 249 * Overide of IUNOXWrapper. 250 * 251 * @param pXInterface the pointer of UNO interface. 252 */ 253 STDMETHODIMP CAccActionBase::put_XInterface(long pXInterface) 254 { 255 256 257 ENTER_PROTECTED_BLOCK 258 259 CUNOXWrapper::put_XInterface(pXInterface); 260 261 //special query. 262 if(pUNOInterface == NULL) 263 return E_FAIL; 264 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 265 if( !pRContext.is() ) 266 return E_FAIL; 267 268 Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY); 269 if( !pRXI.is() ) 270 pRXAct = NULL; 271 else 272 pRXAct = pRXI.get(); 273 return S_OK; 274 275 LEAVE_PROTECTED_BLOCK 276 } 277 278 /** 279 * Helper function used for converting keybinding to string. 280 * 281 * @param keySet the key stroke sequence. 282 * @param pString the output keybinding string. 283 */ 284 void CAccActionBase::GetkeyBindingStrByXkeyBinding( const Sequence< KeyStroke > &keySet, OLECHAR* pString ) 285 { 286 // #CHECK# 287 if(pString == NULL) 288 return; 289 290 for( int iIndex = 0;iIndex < keySet.getLength();iIndex++ ) 291 { 292 KeyStroke stroke = keySet[iIndex]; 293 OLECHAR wString[64] = {NULL}; 294 if(iIndex>0) 295 wcscat( wString, OLESTR(" ") ); 296 if((stroke.Modifiers & MODIFIER_SHIFT) == MODIFIER_SHIFT) 297 wcscat( wString, OLESTR("Shift+") ); 298 if((stroke.Modifiers & MODIFIER_CTRL) == MODIFIER_CTRL) 299 wcscat( wString, OLESTR("Ctrl+") ); 300 if((stroke.Modifiers & MODIFIER_ALT) == MODIFIER_ALT) 301 wcscat( wString, OLESTR("Alt+") ); 302 if(stroke.KeyCode) 303 { 304 OLECHAR* pChar = getOLECHARFromKeyCode(stroke.KeyCode); 305 if(pChar != NULL) 306 wcscat( wString, pChar ); 307 else if (stroke.KeyCode <= 255) 308 { 309 OLECHAR pChar[4] = {NULL}; 310 swprintf( pChar, L"%c", stroke.KeyCode); 311 wcscat( wString, pChar); 312 } 313 else 314 { 315 OLECHAR pChar[4] = {NULL}; 316 swprintf( pChar, L"%d", stroke.KeyCode); 317 wcscat( wString, pChar); 318 } 319 } 320 321 wcscat( pString, wString); 322 } 323 } 324 325 /** 326 * Helper function used for converting key code to ole string. 327 * 328 * @param key the key code. 329 */ 330 OLECHAR* CAccActionBase::getOLECHARFromKeyCode(long key) 331 { 332 static struct keyMap 333 { 334 int keyCode; 335 OLECHAR* key; 336 } 337 map[] = 338 { 339 {MODIFIER_SHIFT, L"SHIFT" }, 340 {MODIFIER_CTRL, L"CTRL" }, 341 {MODIFIER_ALT, L"ALT" }, 342 CODEENTRY(NUM0),CODEENTRY(NUM1),CODEENTRY(NUM2),CODEENTRY(NUM3),CODEENTRY(NUM4),CODEENTRY(NUM5), 343 CODEENTRY(NUM6),CODEENTRY(NUM7),CODEENTRY(NUM8),CODEENTRY(NUM9), 344 CODEENTRY(A),CODEENTRY(B),CODEENTRY(C),CODEENTRY(D),CODEENTRY(E),CODEENTRY(F), 345 CODEENTRY(G),CODEENTRY(H),CODEENTRY(I),CODEENTRY(J),CODEENTRY(K),CODEENTRY(L), 346 CODEENTRY(M),CODEENTRY(N),CODEENTRY(O),CODEENTRY(P),CODEENTRY(Q),CODEENTRY(R), 347 CODEENTRY(S),CODEENTRY(T),CODEENTRY(U),CODEENTRY(V),CODEENTRY(W),CODEENTRY(X), 348 CODEENTRY(Y),CODEENTRY(Z), 349 CODEENTRY(F1),CODEENTRY(F2),CODEENTRY(F3),CODEENTRY(F4),CODEENTRY(F5),CODEENTRY(F6), 350 CODEENTRY(F7),CODEENTRY(F8),CODEENTRY(F9),CODEENTRY(F10),CODEENTRY(F11),CODEENTRY(F12), 351 CODEENTRY(F13),CODEENTRY(F14),CODEENTRY(F15),CODEENTRY(F16),CODEENTRY(F17),CODEENTRY(F18), 352 CODEENTRY(F19),CODEENTRY(F20),CODEENTRY(F21),CODEENTRY(F22),CODEENTRY(F23),CODEENTRY(F24), 353 CODEENTRY(F25),CODEENTRY(F26), 354 355 { KEYCODE_DOWN, L"DOWN" }, 356 { KEYCODE_UP, L"UP" }, 357 { KEYCODE_LEFT, L"LEFT" }, 358 { KEYCODE_RIGHT, L"RIGHT" }, 359 { KEYCODE_HOME, L"HOME" }, 360 { KEYCODE_END, L"END" }, 361 { KEYCODE_PAGEUP, L"PAGEUP" }, 362 { KEYCODE_PAGEDOWN, L"PAGEDOWN" }, 363 { KEYCODE_RETURN, L"RETURN" }, 364 { KEYCODE_ESCAPE, L"ESCAPE" }, 365 { KEYCODE_TAB, L"TAB" }, 366 { KEYCODE_BACKSPACE, L"BACKSPACE" }, 367 { KEYCODE_SPACE, L"SPACE" }, 368 { KEYCODE_INSERT, L"INSERT" }, 369 { KEYCODE_DELETE, L"DELETE" }, 370 { KEYCODE_ADD, L"ADD" }, 371 { KEYCODE_SUBTRACT, L"SUBTRACT" }, 372 { KEYCODE_MULTIPLY, L"MULTIPLY" }, 373 { KEYCODE_DIVIDE, L"DIVIDE" }, 374 { KEYCODE_POINT, L"POINT" }, 375 { KEYCODE_COMMA, L"COMMA" }, 376 { KEYCODE_LESS, L"LESS" }, 377 { KEYCODE_GREATER, L"GREATER" }, 378 { KEYCODE_EQUAL, L"EQUAL" }, 379 { KEYCODE_OPEN, L"OPEN" }, 380 { KEYCODE_CUT, L"CUT" }, 381 { KEYCODE_COPY, L"COPY" }, 382 { KEYCODE_PASTE, L"PASTE" }, 383 { KEYCODE_UNDO, L"UNDO" }, 384 { KEYCODE_REPEAT, L"REPEAT" }, 385 { KEYCODE_FIND, L"FIND" }, 386 { KEYCODE_PROPERTIES, L"PROPERTIES" }, 387 { KEYCODE_FRONT, L"FRONT" }, 388 { KEYCODE_CONTEXTMENU, L"CONTEXTMENU" }, 389 { KEYCODE_HELP, L"HELP" }, 390 }; 391 static long nCount = countof(map); 392 393 long min = 0; 394 long max = nCount-1; 395 long mid = nCount/2; 396 while(min<max) 397 { 398 if(key<map[mid].keyCode) 399 max = mid-1; 400 else if(key>map[mid].keyCode) 401 min = mid+1; 402 else 403 break; 404 mid = (min+max)/2; 405 } 406 407 if(key == map[mid].keyCode) 408 { 409 return map[mid].key; 410 } 411 else 412 { 413 return NULL; 414 } 415 } 416 417