1
/*
2
 * AT-SPI - Assistive Technology Service Provider Interface
3
 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4
 *
5
 * Copyright 2001, 2002 Sun Microsystems Inc.,
6
 * Copyright 2001, 2002 Ximian, Inc.
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the
20
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21
 * Boston, MA 02110-1301, USA.
22
 */
23

            
24
#include "atspi-private.h"
25

            
26
/**
27
 * atspi_document_get_locale:
28
 * @obj: a pointer to the #AtspiDocument object on which to operate.
29
 *
30
 * Gets the locale associated with the document's content,
31
 * e.g. the locale for LOCALE_TYPE_MESSAGES.
32
 *
33
 * Returns: a string compliant with the POSIX standard for locale description.
34
 **/
35
gchar *
36
1
atspi_document_get_locale (AtspiDocument *obj, GError **error)
37
{
38
1
  gchar *retval = NULL;
39

            
40
1
  g_return_val_if_fail (obj != NULL, g_strdup ("C"));
41

            
42
1
  _atspi_dbus_call (obj, atspi_interface_document, "GetLocale", error, "=>s", &retval);
43

            
44
1
  return retval;
45
}
46

            
47
/**
48
 * atspi_document_get_attribute_value: (rename-to atspi_document_get_document_attribute_value)
49
 * @obj: a pointer to the #AtspiDocument object on which to operate.
50
 * @attribute: a string indicating the name of a specific attribute.
51
 *
52
 * Gets the value of a single attribute, if specified for the document as a whole.
53
 *
54
 * Returns: a string corresponding to the value of the specified attribute, or
55
 * an empty string if the attribute is unspecified for the object.
56
 *
57
 * Deprecated: 2.10: Use atspi_document_get_document_attribute_value instead.
58
 **/
59
gchar *
60
atspi_document_get_attribute_value (AtspiDocument *obj,
61
                                    const gchar *attribute,
62
                                    GError **error)
63
{
64
  return atspi_document_get_document_attribute_value (obj, attribute, error);
65
}
66

            
67
/**
68
 * atspi_document_get_document_attribute_value:
69
 * @obj: a pointer to the #AtspiDocument object on which to operate.
70
 * @attribute: a string indicating the name of a specific attribute.
71
 *
72
 * Gets the value of a single attribute, if specified for the document as a whole.
73
 *
74
 * Returns: a string corresponding to the value of the specified attribute, or
75
 * an empty string if the attribute is unspecified for the object.
76
 **/
77
gchar *
78
2
atspi_document_get_document_attribute_value (AtspiDocument *obj,
79
                                             const gchar *attribute,
80
                                             GError **error)
81
{
82
2
  gchar *retval = NULL;
83

            
84
2
  g_return_val_if_fail (obj != NULL, NULL);
85

            
86
2
  _atspi_dbus_call (obj, atspi_interface_document, "GetAttributeValue", error, "s=>s", attribute, &retval);
87

            
88
2
  if (!retval)
89
    retval = g_strdup ("");
90

            
91
2
  return retval;
92
}
93

            
94
/**
95
 * atspi_document_get_attributes: (rename-to atspi_document_get_document_attributes)
96
 * @obj: a pointer to the #AtspiDocument object on which to operate.
97
 *
98
 * Gets all constant attributes for the document as a whole. For attributes
99
 * that change within the document content, see @atspi_text_get_attribute_run instead.
100
 *
101
 * Returns: (element-type gchar* gchar*) (transfer full): a #GHashTable
102
 *          containing the constant attributes of the document, as name-value pairs.
103
 *
104
 * Deprecated: 2.10: Use atspi_document_get_document_attributes instead.
105
 **/
106
GHashTable *
107
atspi_document_get_attributes (AtspiDocument *obj, GError **error)
108
{
109
  return atspi_document_get_document_attributes (obj, error);
110
}
111

            
112
/**
113
 * atspi_document_get_document_attributes:
114
 * @obj: a pointer to the #AtspiDocument object on which to operate.
115
 *
116
 * Gets all constant attributes for the document as a whole. For attributes
117
 * that change within the document content, see @atspi_text_get_attribute_run instead.
118
 *
119
 * Returns: (element-type gchar* gchar*) (transfer full): a #GHashTable
120
 *          containing the constant attributes of the document, as name-value pairs.
121
 **/
122
GHashTable *
123
1
atspi_document_get_document_attributes (AtspiDocument *obj, GError **error)
124
{
125
  DBusMessage *message;
126

            
127
1
  g_return_val_if_fail (obj != NULL, NULL);
128

            
129
1
  message = _atspi_dbus_call_partial (obj, atspi_interface_document, "GetAttributes", error, "");
130
1
  return _atspi_dbus_return_hash_from_message (message);
131
}
132

            
133
/**
134
 * atspi_document_get_page_count:
135
 * @obj: a pointer to the #AtspiDocument object to query.
136
 *
137
 * Gets the page count of an #AccessibleDocument object.
138
 *
139
 * Returns: a #gint indicating the page count of an
140
 * #AccessibleDocument object.
141
 **/
142
gint
143
atspi_document_get_page_count (AtspiDocument *obj, GError **error)
144
{
145
  dbus_int32_t retval = 0;
146

            
147
  g_return_val_if_fail (obj != NULL, -1);
148

            
149
  _atspi_dbus_get_property (obj, atspi_interface_document, "PageCount", error, "i", &retval);
150

            
151
  return retval;
152
}
153

            
154
/**
155
 * atspi_document_get_current_page_number:
156
 * @obj: a pointer to the #AtspiDocument object to query.
157
 *
158
 * Gets the current page number of an #AccessibleDocument object.
159
 *
160
 * Returns: a #gint indicating the current page number in the
161
 * #AccessibleDocument object.
162
 **/
163
gint
164
atspi_document_get_current_page_number (AtspiDocument *obj, GError **error)
165
{
166
  dbus_int32_t retval = 0;
167

            
168
  g_return_val_if_fail (obj != NULL, -1);
169

            
170
  _atspi_dbus_get_property (obj, atspi_interface_document, "CurrentPageNumber", error, "i", &retval);
171

            
172
  return retval;
173
}
174

            
175
static void
176
2
clear_text_selection (void *data)
177
{
178
2
  AtspiTextSelection *selection = data;
179

            
180
2
  g_clear_object (&selection->start_object);
181
2
  g_clear_object (&selection->end_object);
182
2
}
183

            
184
/**
185
 * atspi_document_get_text_selections:
186
 * @document: an #AtspiDocument
187
 *
188
 * Returns an array of AtspiTextSelections within this document.
189
 *
190
 * Returns: (element-type AtspiTextSelection) (transfer full): a GArray of
191
 * AtspiTextSelection structures representing the selection.
192
 *
193
 * Since: 2.52
194
 */
195
GArray *
196
2
atspi_document_get_text_selections (AtspiDocument *obj, GError **error)
197
{
198
  DBusMessage *message;
199
  GArray *selections;
200
  DBusMessageIter iter, iter_array, iter_struct;
201

            
202
2
  g_return_val_if_fail (obj != NULL, NULL);
203

            
204
2
  message = _atspi_dbus_call_partial (obj, atspi_interface_document, "GetTextSelections", error, "");
205
2
  if (!message)
206
    return NULL;
207

            
208
2
  if (strcmp (dbus_message_get_signature (message), "a((so)i(so)ib)") != 0)
209
    {
210
      dbus_message_unref (message);
211
      return NULL;
212
    }
213

            
214
2
  selections = g_array_new (FALSE, TRUE, sizeof (AtspiTextSelection));
215
2
  g_array_set_clear_func (selections, clear_text_selection);
216
2
  dbus_message_iter_init (message, &iter);
217
2
  dbus_message_iter_recurse (&iter, &iter_array);
218

            
219
4
  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
220
    {
221
      AtspiTextSelection selection;
222
2
      dbus_message_iter_recurse (&iter_array, &iter_struct);
223
2
      selection.start_object = _atspi_dbus_consume_accessible (&iter_struct);
224
2
      dbus_message_iter_get_basic (&iter_struct, &selection.start_offset);
225
2
      dbus_message_iter_next (&iter_struct);
226
2
      selection.end_object = _atspi_dbus_consume_accessible (&iter_struct);
227
2
      dbus_message_iter_get_basic (&iter_struct, &selection.end_offset);
228
2
      dbus_message_iter_next (&iter_struct);
229
2
      dbus_message_iter_get_basic (&iter_struct, &selection.start_is_active);
230
2
      g_array_append_val (selections, selection);
231
2
      dbus_message_iter_next (&iter_array);
232
    }
233

            
234
2
  dbus_message_unref (message);
235
2
  return selections;
236
}
237

            
238
static void
239
4
append_accessible_to_iter (DBusMessageIter *iter, AtspiAccessible *accessible)
240
{
241
  DBusMessageIter iter_struct;
242
4
  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL, &iter_struct);
243
4
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &accessible->parent.app->bus_name);
244
4
  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &accessible->parent.path);
245
4
  dbus_message_iter_close_container (iter, &iter_struct);
246
4
}
247

            
248
/**
249
 * atspi_document_set_text_selections:
250
 * @document: an #AtspiDocument.
251
 * @selections: (element-type AtspiTextSelection): a GArray of AtspiTextSelections
252
 *              to be selected.
253
 *
254
 * Makes 1 or more selections within this document denoted by the given
255
 * array of AtspiTextSelections. Any existing physical selection (inside or
256
 * outside this document) is replaced by the new selections. All objects within
257
 * the given selection ranges must be descendants of this document. Otherwise
258
 * FALSE will be returned.
259
 *
260
 * Returns: TRUE if the selection was made successfully; FALSE otherwise.
261
 *
262
 * Since: 2.52
263
 */
264
gboolean
265
1
atspi_document_set_text_selections (AtspiDocument *obj,
266
                                    GArray *selections,
267
                                    GError **error)
268
{
269
  DBusMessage *message, *reply;
270
  AtspiAccessible *accessible;
271
  DBusMessageIter iter, iter_struct, iter_array;
272
  gint i, count;
273
1
  dbus_bool_t ret = FALSE;
274

            
275
1
  g_return_val_if_fail (obj != NULL, FALSE);
276
1
  accessible = ATSPI_ACCESSIBLE (obj);
277

            
278
1
  message = dbus_message_new_method_call (accessible->parent.app->bus_name,
279
1
                                          accessible->parent.path,
280
                                          atspi_interface_document,
281
                                          "SetTextSelections");
282
1
  count = (selections ? selections->len : 0);
283

            
284
1
  dbus_message_iter_init_append (message, &iter);
285
1
  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "((so)i(so)ib)", &iter_array);
286
3
  for (i = 0; i < count; i++)
287
    {
288
2
      dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
289
2
      AtspiTextSelection *item = &g_array_index (selections, AtspiTextSelection, i);
290
2
      append_accessible_to_iter (&iter_struct, item->start_object);
291
2
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &item->start_offset);
292
2
      append_accessible_to_iter (&iter_struct, item->end_object);
293
2
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &item->end_offset);
294
2
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &item->start_is_active);
295
2
      dbus_message_iter_close_container (&iter_array, &iter_struct);
296
    }
297
1
  dbus_message_iter_close_container (&iter, &iter_array);
298

            
299
1
  reply = _atspi_dbus_send_with_reply_and_block (message, error);
300
1
  if (reply)
301
    {
302
1
      dbus_message_get_args (reply, NULL, DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
303
1
      dbus_message_unref (reply);
304
    }
305
1
  return ret;
306
}
307

            
308
static void
309
4
atspi_document_base_init (AtspiDocument *klass)
310
{
311
4
}
312

            
313
GType
314
7
atspi_document_get_type (void)
315
{
316
  static GType type = 0;
317

            
318
7
  if (!type)
319
    {
320
      static const GTypeInfo tinfo = {
321
        sizeof (AtspiDocument),
322
        (GBaseInitFunc) atspi_document_base_init,
323
        (GBaseFinalizeFunc) NULL,
324
      };
325

            
326
2
      type = g_type_register_static (G_TYPE_INTERFACE, "AtspiDocument", &tinfo, 0);
327
    }
328
7
  return type;
329
}