Update ooo320-m1
[ooovba.git] / vcl / unx / gtk / a11y / atkaction.cxx
blobf4f198045794e985148d26395502c6ec402a5ba1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: atkaction.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include "atkwrapper.hxx"
36 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
37 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
39 #include <com/sun/star/awt/Key.hpp>
40 #include <com/sun/star/awt/KeyModifier.hpp>
42 #include <rtl/strbuf.hxx>
43 #include <algorithm>
44 #include <map>
46 #include <stdio.h>
48 using namespace ::com::sun::star;
50 // FIXME
51 static G_CONST_RETURN gchar *
52 getAsConst( const rtl::OString& rString )
54 static const int nMax = 10;
55 static rtl::OString aUgly[nMax];
56 static int nIdx = 0;
57 nIdx = (nIdx + 1) % nMax;
58 aUgly[nIdx] = rString;
59 return aUgly[ nIdx ];
62 static accessibility::XAccessibleAction*
63 getAction( AtkAction *action ) throw (uno::RuntimeException)
65 AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( action );
67 if( pWrap )
69 if( !pWrap->mpAction && pWrap->mpContext )
71 uno::Any any = pWrap->mpContext->queryInterface( accessibility::XAccessibleAction::static_type(NULL) );
72 pWrap->mpAction = reinterpret_cast< accessibility::XAccessibleAction * > (any.pReserved);
73 pWrap->mpAction->acquire();
76 return pWrap->mpAction;
79 return NULL;
82 extern "C" {
84 static gboolean
85 action_wrapper_do_action (AtkAction *action,
86 gint i)
88 try {
89 accessibility::XAccessibleAction* pAction = getAction( action );
90 if( pAction )
91 return pAction->doAccessibleAction( i );
93 catch(const uno::Exception& e) {
94 g_warning( "Exception in doAccessibleAction()" );
97 return FALSE;
100 static gint
101 action_wrapper_get_n_actions (AtkAction *action)
103 try {
104 accessibility::XAccessibleAction* pAction = getAction( action );
105 if( pAction )
106 return pAction->getAccessibleActionCount();
108 catch(const uno::Exception& e) {
109 g_warning( "Exception in getAccessibleActionCount()" );
112 return 0;
115 static G_CONST_RETURN gchar *
116 action_wrapper_get_description (AtkAction *, gint)
118 // GAIL implement this only for cells
119 g_warning( "Not implemented: get_description()" );
120 return "";
123 static G_CONST_RETURN gchar *
124 action_wrapper_get_localized_name (AtkAction *, gint)
126 // GAIL doesn't implement this as well
127 g_warning( "Not implemented: get_localized_name()" );
128 return "";
131 #define ACTION_NAME_PAIR( OOoName, AtkName ) \
132 std::pair< const rtl::OUString, const gchar * > ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OOoName ) ), AtkName )
134 static G_CONST_RETURN gchar *
135 action_wrapper_get_name (AtkAction *action,
136 gint i)
138 static std::map< rtl::OUString, const gchar * > aNameMap;
140 if( aNameMap.empty() )
142 aNameMap.insert( ACTION_NAME_PAIR( "click", "click" ) );
143 aNameMap.insert( ACTION_NAME_PAIR( "select", "click" ) );
144 aNameMap.insert( ACTION_NAME_PAIR( "togglePopup", "push" ) );
147 try {
148 accessibility::XAccessibleAction* pAction = getAction( action );
149 if( pAction )
151 std::map< rtl::OUString, const gchar * >::iterator iter;
153 rtl::OUString aDesc( pAction->getAccessibleActionDescription( i ) );
155 iter = aNameMap.find( aDesc );
156 if( iter != aNameMap.end() )
157 return iter->second;
159 std::pair< const rtl::OUString, const gchar * > aNewVal( aDesc,
160 g_strdup( OUStringToConstGChar(aDesc) ) );
162 if( aNameMap.insert( aNewVal ).second )
163 return aNewVal.second;
166 catch(const uno::Exception& e) {
167 g_warning( "Exception in getAccessibleActionDescription()" );
170 return "";
174 * GNOME Expects a string in the format:
176 * <nmemonic>;<full-path>;<accelerator>
178 * The keybindings in <full-path> should be separated by ":"
181 static inline void
182 appendKeyStrokes(rtl::OStringBuffer& rBuffer, const uno::Sequence< awt::KeyStroke >& rKeyStrokes)
184 for( sal_Int32 i = 0; i < rKeyStrokes.getLength(); i++ )
186 if( rKeyStrokes[i].Modifiers & awt::KeyModifier::SHIFT )
187 rBuffer.append("<Shift>");
188 if( rKeyStrokes[i].Modifiers & awt::KeyModifier::MOD1 )
189 rBuffer.append("<Control>");
190 if( rKeyStrokes[i].Modifiers & awt::KeyModifier::MOD2 )
191 rBuffer.append("<Alt>");
193 if( ( rKeyStrokes[i].KeyCode >= awt::Key::A ) && ( rKeyStrokes[i].KeyCode <= awt::Key::Z ) )
194 rBuffer.append( (sal_Char) ( 'a' + ( rKeyStrokes[i].KeyCode - awt::Key::A ) ) );
195 else
197 sal_Char c = '\0';
199 switch( rKeyStrokes[i].KeyCode )
201 case awt::Key::TAB: c = '\t'; break;
202 case awt::Key::SPACE: c = ' '; break;
203 case awt::Key::ADD: c = '+'; break;
204 case awt::Key::SUBTRACT: c = '-'; break;
205 case awt::Key::MULTIPLY: c = '*'; break;
206 case awt::Key::DIVIDE: c = '/'; break;
207 case awt::Key::POINT: c = '.'; break;
208 case awt::Key::COMMA: c = ','; break;
209 case awt::Key::LESS: c = '<'; break;
210 case awt::Key::GREATER: c = '>'; break;
211 case awt::Key::EQUAL: c = '='; break;
212 case 0:
213 break;
214 default:
215 g_warning( "Unmapped KeyCode: %d", rKeyStrokes[i].KeyCode );
216 break;
219 if( c != '\0' )
220 rBuffer.append( c );
226 static G_CONST_RETURN gchar *
227 action_wrapper_get_keybinding (AtkAction *action,
228 gint i)
230 try {
231 accessibility::XAccessibleAction* pAction = getAction( action );
232 if( pAction )
234 uno::Reference< accessibility::XAccessibleKeyBinding > xBinding( pAction->getAccessibleActionKeyBinding( i ));
236 if( xBinding.is() )
238 rtl::OStringBuffer aRet;
240 sal_Int32 nmax = std::min( xBinding->getAccessibleKeyBindingCount(), (sal_Int32) 3 );
241 for( sal_Int32 n = 0; n < nmax; n++ )
243 appendKeyStrokes( aRet, xBinding->getAccessibleKeyBinding( n ) );
245 if( n < 2 )
246 aRet.append( (sal_Char) ';' );
249 // !! FIXME !! remember keystroke in wrapper object ?
250 return getAsConst( aRet.makeStringAndClear() );
254 catch(const uno::Exception& e) {
255 g_warning( "Exception in get_keybinding()" );
258 return "";
261 static gboolean
262 action_wrapper_set_description (AtkAction *, gint, const gchar *)
264 return FALSE;
267 } // extern "C"
269 void
270 actionIfaceInit (AtkActionIface *iface)
272 g_return_if_fail (iface != NULL);
274 iface->do_action = action_wrapper_do_action;
275 iface->get_n_actions = action_wrapper_get_n_actions;
276 iface->get_description = action_wrapper_get_description;
277 iface->get_keybinding = action_wrapper_get_keybinding;
278 iface->get_name = action_wrapper_get_name;
279 iface->get_localized_name = action_wrapper_get_localized_name;
280 iface->set_description = action_wrapper_set_description;