* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <gtk/gtk.h>
#include "gtkmenuitemaccessible.h"
-#include "gtksubmenuitemaccessible.h"
#include "gtk/gtkmenuitemprivate.h"
+struct _GtkMenuItemAccessiblePrivate
+{
+ gchar *text;
+};
+
#define KEYBINDING_SEPARATOR ";"
static void menu_item_select (GtkMenuItem *item);
static GtkWidget *get_label_from_container (GtkWidget *container);
static gchar *get_text_from_label_widget (GtkWidget *widget);
+static gint menu_item_add_gtk (GtkContainer *container,
+ GtkWidget *widget);
+static gint menu_item_remove_gtk (GtkContainer *container,
+ GtkWidget *widget);
-static void atk_action_interface_init (AtkActionIface *iface);
+static void atk_action_interface_init (AtkActionIface *iface);
+static void atk_selection_interface_init (AtkSelectionIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkMenuItemAccessible, _gtk_menu_item_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init);
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
static void
gtk_menu_item_accessible_initialize (AtkObject *obj,
{
GtkWidget *widget;
GtkWidget *parent;
+ GtkWidget *menu;
ATK_OBJECT_CLASS (_gtk_menu_item_accessible_parent_class)->initialize (obj, data);
atk_object_set_parent (obj, gtk_widget_get_accessible (parent_widget));
}
- GTK_WIDGET_ACCESSIBLE (obj)->layer = ATK_LAYER_POPUP;
+ _gtk_widget_accessible_set_layer (GTK_WIDGET_ACCESSIBLE (obj), ATK_LAYER_POPUP);
- if (GTK_IS_TEAROFF_MENU_ITEM (data))
- obj->role = ATK_ROLE_TEAR_OFF_MENU_ITEM;
- else
- obj->role = ATK_ROLE_MENU_ITEM;
+ obj->role = ATK_ROLE_MENU_ITEM;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (data));
+ if (menu)
+ {
+ g_signal_connect (menu, "add", G_CALLBACK (menu_item_add_gtk), NULL);
+ g_signal_connect (menu, "remove", G_CALLBACK (menu_item_remove_gtk), NULL);
+ }
}
static gint
accessible = GTK_MENU_ITEM_ACCESSIBLE (obj);
label = get_label_from_container (widget);
- g_free (accessible->text);
- accessible->text = get_text_from_label_widget (label);
+ g_free (accessible->priv->text);
+ accessible->priv->text = get_text_from_label_widget (label);
- return accessible->text;
+ return accessible->priv->text;
}
static void
{
GtkMenuItemAccessible *accessible = GTK_MENU_ITEM_ACCESSIBLE (object);
- g_free (accessible->text);
+ g_free (accessible->priv->text);
G_OBJECT_CLASS (_gtk_menu_item_accessible_parent_class)->finalize (object);
}
class->initialize = gtk_menu_item_accessible_initialize;
class->get_name = gtk_menu_item_accessible_get_name;
class->get_role = gtk_menu_item_accessible_get_role;
+
+ g_type_class_add_private (klass, sizeof (GtkMenuItemAccessiblePrivate));
}
static void
_gtk_menu_item_accessible_init (GtkMenuItemAccessible *menu_item)
{
+ menu_item->priv = G_TYPE_INSTANCE_GET_PRIVATE (menu_item,
+ GTK_TYPE_MENU_ITEM_ACCESSIBLE,
+ GtkMenuItemAccessiblePrivate);
}
static GtkWidget *
g_signal_emit_by_name (parent, "selection-changed");
}
+static gboolean
+gtk_menu_item_accessible_add_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ GList *kids;
+ guint length;
+ GtkWidget *widget;
+ GtkWidget *menu;
+ GtkWidget *child;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ return FALSE;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (menu == NULL)
+ return FALSE;
+
+ shell = GTK_MENU_SHELL (menu);
+ kids = gtk_container_get_children (GTK_CONTAINER (shell));
+ length = g_list_length (kids);
+ if (i < 0 || i > length)
+ {
+ g_list_free (kids);
+ return FALSE;
+ }
+
+ child = g_list_nth_data (kids, i);
+ g_list_free (kids);
+ g_return_val_if_fail (GTK_IS_MENU_ITEM (child), FALSE);
+ gtk_menu_shell_select_item (shell, GTK_WIDGET (child));
+ return TRUE;
+}
+
+static gboolean
+gtk_menu_item_accessible_clear_selection (AtkSelection *selection)
+{
+ GtkWidget *widget;
+ GtkWidget *menu;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ return FALSE;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (menu == NULL)
+ return FALSE;
+
+ gtk_menu_shell_deselect (GTK_MENU_SHELL (menu));
+
+ return TRUE;
+}
+
+static AtkObject *
+gtk_menu_item_accessible_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ AtkObject *obj;
+ GtkWidget *widget;
+ GtkWidget *menu;
+ GtkWidget *item;
+
+ if (i != 0)
+ return NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ return NULL;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (menu == NULL)
+ return NULL;
+
+ shell = GTK_MENU_SHELL (menu);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item != NULL)
+ {
+ obj = gtk_widget_get_accessible (item);
+ g_object_ref (obj);
+ return obj;
+ }
+
+ return NULL;
+}
+
+static gint
+gtk_menu_item_accessible_get_selection_count (AtkSelection *selection)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+ GtkWidget *menu;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ return 0;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (menu == NULL)
+ return 0;
+
+ shell = GTK_MENU_SHELL (menu);
+
+ if (gtk_menu_shell_get_selected_item (shell) != NULL)
+ return 1;
+
+ return 0;
+}
+
+static gboolean
+gtk_menu_item_accessible_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ gint j;
+ GtkWidget *widget;
+ GtkWidget *menu;
+ GtkWidget *item;
+ GList *kids;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ return FALSE;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (menu == NULL)
+ return FALSE;
+
+ shell = GTK_MENU_SHELL (menu);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item == NULL)
+ return FALSE;
+
+ kids = gtk_container_get_children (GTK_CONTAINER (shell));
+ j = g_list_index (kids, item);
+ g_list_free (kids);
+
+ return j==i;
+}
+
+static gboolean
+gtk_menu_item_accessible_remove_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+ GtkWidget *menu;
+ GtkWidget *item;
+
+ if (i != 0)
+ return FALSE;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ return FALSE;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (menu == NULL)
+ return FALSE;
+
+ shell = GTK_MENU_SHELL (menu);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
+ gtk_menu_shell_deselect (shell);
+
+ return TRUE;
+}
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = gtk_menu_item_accessible_add_selection;
+ iface->clear_selection = gtk_menu_item_accessible_clear_selection;
+ iface->ref_selection = gtk_menu_item_accessible_ref_selection;
+ iface->get_selection_count = gtk_menu_item_accessible_get_selection_count;
+ iface->is_child_selected = gtk_menu_item_accessible_is_child_selected;
+ iface->remove_selection = gtk_menu_item_accessible_remove_selection;
+}
+
+static gint
+menu_item_add_gtk (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GtkWidget *parent_widget;
+
+ g_return_val_if_fail (GTK_IS_MENU (container), 1);
+
+ parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
+ if (GTK_IS_MENU_ITEM (parent_widget))
+ {
+ GTK_CONTAINER_ACCESSIBLE_CLASS (_gtk_menu_item_accessible_parent_class)->add_gtk (container, widget, gtk_widget_get_accessible (parent_widget));
+
+ }
+ return 1;
+}
+
+static gint
+menu_item_remove_gtk (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GtkWidget *parent_widget;
+
+ g_return_val_if_fail (GTK_IS_MENU (container), 1);
+
+ parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
+ if (GTK_IS_MENU_ITEM (parent_widget))
+ {
+ GTK_CONTAINER_ACCESSIBLE_CLASS (_gtk_menu_item_accessible_parent_class)->remove_gtk (container, widget, gtk_widget_get_accessible (parent_widget));
+ }
+ return 1;
+}
static void
menu_item_select (GtkMenuItem *item)
{