Move setting of LD_LIBRARY_PATH closer to invocation of cppunittester
[LibreOffice.git] / vcl / unx / gtk3 / a11y / atkaction.cxx
blob09db51556936e2eba992c5da33f27c30f67b345c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
29 #include <algorithm>
30 #include <map>
32 using namespace ::com::sun::star;
34 // FIXME
35 static const gchar *
36 getAsConst( const OString& rString )
38 static const int nMax = 10;
39 static OString aUgly[nMax];
40 static int nIdx = 0;
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 );
52 if( pWrap )
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>();
65 extern "C" {
67 static gboolean
68 action_wrapper_do_action (AtkAction *action,
69 gint i)
71 try {
72 css::uno::Reference<css::accessibility::XAccessibleAction> pAction
73 = getAction( action );
74 if( pAction.is() )
75 return pAction->doAccessibleAction( i );
77 catch(const uno::Exception&) {
78 g_warning( "Exception in doAccessibleAction()" );
81 return FALSE;
84 static gint
85 action_wrapper_get_n_actions (AtkAction *action)
87 try {
88 css::uno::Reference<css::accessibility::XAccessibleAction> pAction
89 = getAction( action );
90 if( pAction.is() )
91 return pAction->getAccessibleActionCount();
93 catch(const uno::Exception&) {
94 g_warning( "Exception in getAccessibleActionCount()" );
97 return 0;
100 static const gchar *
101 action_wrapper_get_description (AtkAction *, gint)
103 // GAIL implement this only for cells
104 g_warning( "Not implemented: get_description()" );
105 return "";
108 static const gchar *
109 action_wrapper_get_localized_name (AtkAction *, gint)
111 // GAIL doesn't implement this as well
112 g_warning( "Not implemented: get_localized_name()" );
113 return "";
116 static const gchar *
117 action_wrapper_get_name (AtkAction *action,
118 gint i)
120 static std::map< OUString, const gchar * > aNameMap {
121 { "click", "click" },
122 { "select", "click" } ,
123 { "togglePopup", "push" }
126 try {
127 css::uno::Reference<css::accessibility::XAccessibleAction> pAction
128 = getAction( action );
129 if( pAction.is() )
131 std::map< OUString, const gchar * >::iterator iter;
133 OUString aDesc( pAction->getAccessibleActionDescription( i ) );
135 iter = aNameMap.find( aDesc );
136 if( iter != aNameMap.end() )
137 return iter->second;
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()" );
150 return "";
154 * GNOME Expects a string in the format:
156 * <mnemonic>;<full-path>;<accelerator>
158 * The keybindings in <full-path> should be separated by ":"
161 static void
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 ) ) );
175 else
177 char c = '\0';
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;
192 case 0:
193 break;
194 default:
195 g_warning( "Unmapped KeyCode: %d", rKeyStroke.KeyCode );
196 break;
199 if( c != '\0' )
200 rBuffer.append( c );
201 else
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));
211 static const gchar *
212 action_wrapper_get_keybinding (AtkAction *action,
213 gint i)
215 try {
216 css::uno::Reference<css::accessibility::XAccessibleAction> pAction
217 = getAction( action );
218 if( pAction.is() )
220 uno::Reference< accessibility::XAccessibleKeyBinding > xBinding( pAction->getAccessibleActionKeyBinding( i ));
222 if( xBinding.is() )
224 OStringBuffer aRet;
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 ) );
231 if( n < 2 )
232 aRet.append( ';' );
235 // !! FIXME !! remember keystroke in wrapper object ?
236 return getAsConst( aRet.makeStringAndClear() );
240 catch(const uno::Exception&) {
241 g_warning( "Exception in get_keybinding()" );
244 return "";
247 static gboolean
248 action_wrapper_set_description (AtkAction *, gint, const gchar *)
250 return FALSE;
253 } // extern "C"
255 void
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: */