From 39ea09732c05f4b4d1a609e0cdea452d891c1327 Mon Sep 17 00:00:00 2001
From: Joanmarie Diggs <jdiggs@igalia.com>
Date: Wed, 30 Jul 2014 17:50:04 +0200
Subject: [PATCH] libview: Emit accessible state-changed signals for form
 fields

---
 libview/ev-form-field-accessible.c | 32 ++++++++++++++++++++++++++++++++
 libview/ev-form-field-accessible.h |  1 +
 libview/ev-page-accessible.c       | 14 ++++++++++++++
 libview/ev-page-accessible.h       |  2 ++
 libview/ev-view-accessible.c       | 11 +++++++++++
 libview/ev-view-accessible.h       |  3 +++
 libview/ev-view.c                  |  5 +++++
 7 files changed, 68 insertions(+)

diff --git a/libview/ev-form-field-accessible.c b/libview/ev-form-field-accessible.c
index 0b38e52..8187d83 100644
--- a/libview/ev-form-field-accessible.c
+++ b/libview/ev-form-field-accessible.c
@@ -32,6 +32,8 @@ struct _EvFormFieldAccessiblePrivate {
 	gchar            *name;
 	gint              start_index;
 	gint              end_index;
+
+	AtkStateSet      *saved_states;
 };
 
 static void ev_form_field_accessible_component_iface_init (AtkComponentIface *iface);
@@ -308,6 +310,33 @@ ev_form_field_accessible_ref_state_set (AtkObject *atk_object)
 	return copy_set;
 }
 
+void
+ev_form_field_accessible_update_state (EvFormFieldAccessible *accessible)
+{
+	AtkObject *atk_object;
+	AtkStateSet *states;
+	AtkStateSet *changed_states;
+	gint i;
+
+	atk_object = ATK_OBJECT (accessible);
+	states = ev_form_field_accessible_ref_state_set (atk_object);
+	changed_states = atk_state_set_xor_sets (accessible->priv->saved_states, states);
+	if (changed_states && !atk_state_set_is_empty (accessible->priv->saved_states)) {
+		for (i = 0; i < ATK_STATE_LAST_DEFINED; i++) {
+			if (atk_state_set_contains_state (changed_states, i))
+				atk_object_notify_state_change (atk_object, i, atk_state_set_contains_state (states, i));
+		}
+	}
+
+	g_object_unref (accessible->priv->saved_states);
+
+	atk_state_set_clear_states (changed_states);
+	accessible->priv->saved_states = atk_state_set_or_sets (changed_states, states);
+
+	g_object_unref (changed_states);
+	g_object_unref (states);
+}
+
 static void
 ev_form_field_accessible_finalize (GObject *object)
 {
@@ -315,6 +344,7 @@ ev_form_field_accessible_finalize (GObject *object)
 
 	g_object_unref (priv->form_field);
 	g_free (priv->name);
+	g_object_unref (priv->saved_states);
 
 	G_OBJECT_CLASS (ev_form_field_accessible_parent_class)->finalize (object);
 }
@@ -353,6 +383,8 @@ ev_form_field_accessible_new (EvPageAccessible *page,
 	atk_form_field->priv->page = page;
 	atk_form_field->priv->form_field = g_object_ref (form_field);
 	atk_form_field->priv->area = *area;
+	atk_form_field->priv->saved_states = atk_state_set_new ();
+	ev_form_field_accessible_update_state (atk_form_field);
 
 	return EV_FORM_FIELD_ACCESSIBLE (atk_form_field);
 }
diff --git a/libview/ev-form-field-accessible.h b/libview/ev-form-field-accessible.h
index d60a9c8..572e1ef 100644
--- a/libview/ev-form-field-accessible.h
+++ b/libview/ev-form-field-accessible.h
@@ -52,5 +52,6 @@ EvFormFieldAccessible *ev_form_field_accessible_new (EvPageAccessible *page,
 						     EvFormField      *form_field,
 						     EvRectangle      *area);
 EvFormField           *ev_form_field_accessible_get_field (EvFormFieldAccessible *accessible);
+void                   ev_form_field_accessible_update_state (EvFormFieldAccessible *accessible);
 
 #endif  /* __EV_FORM_FIELD_ACCESSIBLE_H__ */
diff --git a/libview/ev-page-accessible.c b/libview/ev-page-accessible.c
index eeed659..6cbccc9 100644
--- a/libview/ev-page-accessible.c
+++ b/libview/ev-page-accessible.c
@@ -1245,3 +1245,17 @@ ev_page_accessible_get_accessible_for_mapping (EvPageAccessible *page_accessible
 
 	return NULL;
 }
+
+void
+ev_page_accessible_update_element_state (EvPageAccessible *page_accessible,
+					 EvMapping        *mapping)
+{
+	AtkObject *child;
+
+	child = ev_page_accessible_get_accessible_for_mapping (page_accessible, mapping);
+	if (!child)
+		return;
+
+	if (EV_IS_FORM_FIELD_ACCESSIBLE (child))
+		ev_form_field_accessible_update_state (EV_FORM_FIELD_ACCESSIBLE (child));
+}
diff --git a/libview/ev-page-accessible.h b/libview/ev-page-accessible.h
index 2c0e242..b59816e 100644
--- a/libview/ev-page-accessible.h
+++ b/libview/ev-page-accessible.h
@@ -53,6 +53,8 @@ EvViewAccessible *ev_page_accessible_get_view_accessible (EvPageAccessible *page
 EvView           *ev_page_accessible_get_view            (EvPageAccessible *page_accessible);
 AtkObject        *ev_page_accessible_get_accessible_for_mapping (EvPageAccessible *page_accessible,
 								 EvMapping        *mapping);
+void              ev_page_accessible_update_element_state (EvPageAccessible *page_accessible,
+							   EvMapping        *mapping);
 
 #endif  /* __EV_PAGE_ACCESSIBLE_H__ */
 
diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c
index c7288b4..ffc617c 100644
--- a/libview/ev-view-accessible.c
+++ b/libview/ev-view-accessible.c
@@ -615,3 +615,14 @@ ev_view_accessible_set_focused_element (EvViewAccessible *accessible,
 	if (accessible->priv->focused_element)
 		atk_object_notify_state_change (accessible->priv->focused_element, ATK_STATE_FOCUSED, TRUE);
 }
+
+void
+ev_view_accessible_update_element_state (EvViewAccessible *accessible,
+					 EvMapping        *element,
+					 gint              element_page)
+{
+	EvPageAccessible *page;
+
+	page = g_ptr_array_index (accessible->priv->children, element_page);
+	ev_page_accessible_update_element_state (page, element);
+}
diff --git a/libview/ev-view-accessible.h b/libview/ev-view-accessible.h
index d61540e..14c3ac9 100644
--- a/libview/ev-view-accessible.h
+++ b/libview/ev-view-accessible.h
@@ -68,6 +68,9 @@ gboolean  ev_view_accessible_is_doc_rect_showing (EvViewAccessible *accessible,
 void       ev_view_accessible_set_focused_element (EvViewAccessible *accessible,
 						   EvMapping        *new_focus,
 						   gint              new_focus_page);
+void       ev_view_accessible_update_element_state (EvViewAccessible *accessible,
+						    EvMapping        *element,
+						    gint              element_page);
 
 #endif  /* __EV_VIEW_ACCESSIBLE_H__ */
 
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 4c346e9..4b64e22 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -2304,6 +2304,11 @@ ev_view_form_field_button_toggle (EvView      *view,
 						       !state);
 	field_button->state = !state;
 
+	if (view->accessible)
+		ev_view_accessible_update_element_state (EV_VIEW_ACCESSIBLE (view->accessible),
+							 ev_mapping_list_find (forms_mapping, field),
+							 field->page->index);
+
 	ev_view_reload_page (view, field->page->index, region);
 	cairo_region_destroy (region);
 }
-- 
1.9.3

