1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "atkwrapper.hxx"
22 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
23 #include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
25 #include <com/sun/star/awt/Key.hpp>
26 #include <com/sun/star/awt/KeyModifier.hpp>
28 #include <rtl/strbuf.hxx>
32 using namespace ::com::sun::star
;
36 getAsConst( const OString
& rString
)
38 static const int nMax
= 10;
39 static OString aUgly
[nMax
];
41 nIdx
= (nIdx
+ 1) % nMax
;
42 aUgly
[nIdx
] = rString
;
43 return aUgly
[ nIdx
].getStr();
46 /// @throws uno::RuntimeException
47 static css::uno::Reference
<css::accessibility::XAccessibleAction
>
48 getAction( AtkAction
*action
)
50 AtkObjectWrapper
*pWrap
= ATK_OBJECT_WRAPPER( action
);
54 if( !pWrap
->mpAction
.is() )
56 pWrap
->mpAction
.set(pWrap
->mpContext
, css::uno::UNO_QUERY
);
59 return pWrap
->mpAction
;
62 return css::uno::Reference
<css::accessibility::XAccessibleAction
>();
68 action_wrapper_do_action (AtkAction
*action
,
72 css::uno::Reference
<css::accessibility::XAccessibleAction
> pAction
73 = getAction( action
);
75 return pAction
->doAccessibleAction( i
);
77 catch(const uno::Exception
&) {
78 g_warning( "Exception in doAccessibleAction()" );
85 action_wrapper_get_n_actions (AtkAction
*action
)
88 css::uno::Reference
<css::accessibility::XAccessibleAction
> pAction
89 = getAction( action
);
91 return pAction
->getAccessibleActionCount();
93 catch(const uno::Exception
&) {
94 g_warning( "Exception in getAccessibleActionCount()" );
101 action_wrapper_get_description (AtkAction
*, gint
)
103 // GAIL implement this only for cells
104 g_warning( "Not implemented: get_description()" );
109 action_wrapper_get_localized_name (AtkAction
*, gint
)
111 // GAIL doesn't implement this as well
112 g_warning( "Not implemented: get_localized_name()" );
117 action_wrapper_get_name (AtkAction
*action
,
120 static std::map
< OUString
, const gchar
* > aNameMap
{
121 { "click", "click" },
122 { "select", "click" } ,
123 { "togglePopup", "push" }
127 css::uno::Reference
<css::accessibility::XAccessibleAction
> pAction
128 = getAction( action
);
131 std::map
< OUString
, const gchar
* >::iterator iter
;
133 OUString
aDesc( pAction
->getAccessibleActionDescription( i
) );
135 iter
= aNameMap
.find( aDesc
);
136 if( iter
!= aNameMap
.end() )
139 std::pair
< const OUString
, const gchar
* > aNewVal( aDesc
,
140 g_strdup( OUStringToConstGChar(aDesc
) ) );
142 if( aNameMap
.insert( aNewVal
).second
)
143 return aNewVal
.second
;
146 catch(const uno::Exception
&) {
147 g_warning( "Exception in getAccessibleActionDescription()" );
154 * GNOME Expects a string in the format:
156 * <mnemonic>;<full-path>;<accelerator>
158 * The keybindings in <full-path> should be separated by ":"
162 appendKeyStrokes(OStringBuffer
& rBuffer
, const uno::Sequence
< awt::KeyStroke
>& rKeyStrokes
)
164 for( const auto& rKeyStroke
: rKeyStrokes
)
166 if( rKeyStroke
.Modifiers
& awt::KeyModifier::SHIFT
)
167 rBuffer
.append("<Shift>");
168 if( rKeyStroke
.Modifiers
& awt::KeyModifier::MOD1
)
169 rBuffer
.append("<Control>");
170 if( rKeyStroke
.Modifiers
& awt::KeyModifier::MOD2
)
171 rBuffer
.append("<Alt>");
173 if( ( rKeyStroke
.KeyCode
>= awt::Key::A
) && ( rKeyStroke
.KeyCode
<= awt::Key::Z
) )
174 rBuffer
.append( static_cast<char>( 'a' + ( rKeyStroke
.KeyCode
- awt::Key::A
) ) );
179 switch( rKeyStroke
.KeyCode
)
181 case awt::Key::TAB
: c
= '\t'; break;
182 case awt::Key::SPACE
: c
= ' '; break;
183 case awt::Key::ADD
: c
= '+'; break;
184 case awt::Key::SUBTRACT
: c
= '-'; break;
185 case awt::Key::MULTIPLY
: c
= '*'; break;
186 case awt::Key::DIVIDE
: c
= '/'; break;
187 case awt::Key::POINT
: c
= '.'; break;
188 case awt::Key::COMMA
: c
= ','; break;
189 case awt::Key::LESS
: c
= '<'; break;
190 case awt::Key::GREATER
: c
= '>'; break;
191 case awt::Key::EQUAL
: c
= '='; break;
195 g_warning( "Unmapped KeyCode: %d", rKeyStroke
.KeyCode
);
203 // The KeyCode approach did not work, probably a non ascii character
204 // let's hope that there is a character given in KeyChar.
205 rBuffer
.append(OUStringToOString(OUStringChar(rKeyStroke
.KeyChar
), RTL_TEXTENCODING_UTF8
));
212 action_wrapper_get_keybinding (AtkAction
*action
,
216 css::uno::Reference
<css::accessibility::XAccessibleAction
> pAction
217 = getAction( action
);
220 uno::Reference
< accessibility::XAccessibleKeyBinding
> xBinding( pAction
->getAccessibleActionKeyBinding( i
));
226 sal_Int32 nmax
= std::min( xBinding
->getAccessibleKeyBindingCount(), sal_Int32(3) );
227 for( sal_Int32 n
= 0; n
< nmax
; n
++ )
229 appendKeyStrokes( aRet
, xBinding
->getAccessibleKeyBinding( n
) );
235 // !! FIXME !! remember keystroke in wrapper object ?
236 return getAsConst( aRet
.makeStringAndClear() );
240 catch(const uno::Exception
&) {
241 g_warning( "Exception in get_keybinding()" );
248 action_wrapper_set_description (AtkAction
*, gint
, const gchar
*)
256 actionIfaceInit (gpointer iface_
, gpointer
)
258 auto const iface
= static_cast<AtkActionIface
*>(iface_
);
259 g_return_if_fail (iface
!= nullptr);
261 iface
->do_action
= action_wrapper_do_action
;
262 iface
->get_n_actions
= action_wrapper_get_n_actions
;
263 iface
->get_description
= action_wrapper_get_description
;
264 iface
->get_keybinding
= action_wrapper_get_keybinding
;
265 iface
->get_name
= action_wrapper_get_name
;
266 iface
->get_localized_name
= action_wrapper_get_localized_name
;
267 iface
->set_description
= action_wrapper_set_description
;
270 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */