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