1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "atkwrapper.hxx"
21 #include "atktextattributes.hxx"
22 
23 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
24 
25 #include <string.h>
26 
27 using namespace ::com::sun::star;
28 
29 /// @throws uno::RuntimeException
30 static css::uno::Reference<css::accessibility::XAccessibleEditableText>
getEditableText(AtkEditableText * pEditableText)31     getEditableText( AtkEditableText *pEditableText )
32 {
33     AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pEditableText );
34     if( pWrap )
35     {
36         if( !pWrap->mpEditableText.is() )
37         {
38             pWrap->mpEditableText.set(pWrap->mpContext, css::uno::UNO_QUERY);
39         }
40 
41         return pWrap->mpEditableText;
42     }
43 
44     return css::uno::Reference<css::accessibility::XAccessibleEditableText>();
45 }
46 
47 /*****************************************************************************/
48 
49 extern "C" {
50 
51 static gboolean
editable_text_wrapper_set_run_attributes(AtkEditableText * text,AtkAttributeSet * attribute_set,gint nStartOffset,gint nEndOffset)52 editable_text_wrapper_set_run_attributes( AtkEditableText  *text,
53                                           AtkAttributeSet  *attribute_set,
54                                           gint              nStartOffset,
55                                           gint              nEndOffset)
56 {
57     try {
58         css::uno::Reference<css::accessibility::XAccessibleEditableText>
59             pEditableText = getEditableText( text );
60         if( pEditableText.is() )
61         {
62             uno::Sequence< beans::PropertyValue > aAttributeList;
63 
64             if( attribute_set_map_to_property_values( attribute_set, aAttributeList ) )
65                 return pEditableText->setAttributes(nStartOffset, nEndOffset, aAttributeList);
66         }
67     }
68     catch(const uno::Exception&) {
69         g_warning( "Exception in setAttributes()" );
70     }
71 
72     return FALSE;
73 }
74 
75 static void
editable_text_wrapper_set_text_contents(AtkEditableText * text,const gchar * string)76 editable_text_wrapper_set_text_contents( AtkEditableText  *text,
77                                          const gchar      *string )
78 {
79     try {
80         css::uno::Reference<css::accessibility::XAccessibleEditableText>
81             pEditableText = getEditableText( text );
82         if( pEditableText.is() )
83         {
84             OUString aString ( string, strlen(string), RTL_TEXTENCODING_UTF8 );
85             pEditableText->setText( aString );
86         }
87     }
88     catch(const uno::Exception&) {
89         g_warning( "Exception in setText()" );
90     }
91 }
92 
93 static void
editable_text_wrapper_insert_text(AtkEditableText * text,const gchar * string,gint length,gint * pos)94 editable_text_wrapper_insert_text( AtkEditableText  *text,
95                                    const gchar      *string,
96                                    gint             length,
97                                    gint             *pos )
98 {
99     try {
100         css::uno::Reference<css::accessibility::XAccessibleEditableText>
101             pEditableText = getEditableText( text );
102         if( pEditableText.is() )
103         {
104             OUString aString ( string, length, RTL_TEXTENCODING_UTF8 );
105             if( pEditableText->insertText( aString, *pos ) )
106                 *pos += length;
107         }
108     }
109     catch(const uno::Exception&) {
110         g_warning( "Exception in insertText()" );
111     }
112 }
113 
114 static void
editable_text_wrapper_cut_text(AtkEditableText * text,gint start,gint end)115 editable_text_wrapper_cut_text( AtkEditableText  *text,
116                                 gint             start,
117                                 gint             end )
118 {
119     try {
120         css::uno::Reference<css::accessibility::XAccessibleEditableText>
121             pEditableText = getEditableText( text );
122         if( pEditableText.is() )
123             pEditableText->cutText( start, end );
124     }
125     catch(const uno::Exception&) {
126         g_warning( "Exception in cutText()" );
127     }
128 }
129 
130 static void
editable_text_wrapper_delete_text(AtkEditableText * text,gint start,gint end)131 editable_text_wrapper_delete_text( AtkEditableText  *text,
132                                    gint             start,
133                                    gint             end )
134 {
135     try {
136         css::uno::Reference<css::accessibility::XAccessibleEditableText>
137             pEditableText = getEditableText( text );
138         if( pEditableText.is() )
139             pEditableText->deleteText( start, end );
140     }
141     catch(const uno::Exception&) {
142         g_warning( "Exception in deleteText()" );
143     }
144 }
145 
146 static void
editable_text_wrapper_paste_text(AtkEditableText * text,gint pos)147 editable_text_wrapper_paste_text( AtkEditableText  *text,
148                                   gint             pos )
149 {
150     try {
151         css::uno::Reference<css::accessibility::XAccessibleEditableText>
152             pEditableText = getEditableText( text );
153         if( pEditableText.is() )
154             pEditableText->pasteText( pos );
155     }
156     catch(const uno::Exception&) {
157         g_warning( "Exception in pasteText()" );
158     }
159 }
160 
161 static void
editable_text_wrapper_copy_text(AtkEditableText * text,gint start,gint end)162 editable_text_wrapper_copy_text( AtkEditableText  *text,
163                                  gint             start,
164                                  gint             end )
165 {
166     try {
167         css::uno::Reference<css::accessibility::XAccessibleEditableText>
168             pEditableText = getEditableText( text );
169         if( pEditableText.is() )
170             pEditableText->copyText( start, end );
171     }
172     catch(const uno::Exception&) {
173         g_warning( "Exception in copyText()" );
174     }
175 }
176 
177 } // extern "C"
178 
179 void
editableTextIfaceInit(AtkEditableTextIface * iface)180 editableTextIfaceInit (AtkEditableTextIface *iface)
181 {
182   g_return_if_fail (iface != nullptr);
183 
184   iface->set_text_contents = editable_text_wrapper_set_text_contents;
185   iface->insert_text = editable_text_wrapper_insert_text;
186   iface->copy_text = editable_text_wrapper_copy_text;
187   iface->cut_text = editable_text_wrapper_cut_text;
188   iface->delete_text = editable_text_wrapper_delete_text;
189   iface->paste_text = editable_text_wrapper_paste_text;
190   iface->set_run_attributes = editable_text_wrapper_set_run_attributes;
191 }
192 
193 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
194