[almanah] accessibility: Improve the accessibility around the application.



commit cc5c3e34e98f070eeb8503eff205db305c996bd0
Author: Álvaro Peña <alvaropg gmail com>
Date:   Sun Nov 17 17:36:06 2013 +0100

    accessibility: Improve the accessibility around the application.
    
    Now the AlmanahTag accept the focus and export the action "remove" with the
    implementation of the AtkAction interface.
    
    The main window now have access to the UI manager accellerators.

 src/Makefile.am               |    2 +
 src/main-window.c             |    6 +-
 src/widgets/entry-tags-area.c |    1 +
 src/widgets/tag-accessible.c  |  168 +++++++++++++++++++++++++++++++++++++++++
 src/widgets/tag-accessible.h  |   51 ++++++++++++
 src/widgets/tag-entry.c       |  144 ++++++++++++++++++-----------------
 src/widgets/tag.c             |   29 ++++++-
 src/widgets/tag.h             |    7 +-
 8 files changed, 331 insertions(+), 77 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 944140c..e50c3c3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,6 +48,8 @@ almanah_SOURCES = \
        widgets/entry-tags-area.c               \
        widgets/hyperlink-tag.c                 \
        widgets/hyperlink-tag.h                 \
+       widgets/tag-accessible.c                \
+       widgets/tag-accessible.h                \
        widgets/tag.c                           \
        widgets/tag.h                           \
        widgets/tag-entry.c                     \
diff --git a/src/main-window.c b/src/main-window.c
index 04376d3..83b76bc 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -244,7 +244,7 @@ almanah_main_window_new (AlmanahApplication *application)
 
        /* We don't use g_settings_bind() because enabling spell checking could fail, and we need to show an 
error dialogue */
        priv->spell_checking_enabled_changed_id = g_signal_connect (priv->settings, 
"changed::spell-checking-enabled",
-                                                                   (GCallback) 
spell_checking_enabled_changed_cb, main_window);
+                                                                   (GCallback) 
spell_checking_enabled_changed_cb, main_window);
 #endif /* ENABLE_SPELL_CHECKING */
 
        /* Set up text formatting. It's important this is done after setting up GtkSpell, so that we know 
whether to
@@ -1253,6 +1253,10 @@ mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *applicatio
        toolbar = GTK_TOOLBAR (gtk_builder_get_object (builder, "almanah_mw_toolbar"));
        manager = GTK_UI_MANAGER (gtk_builder_get_object (builder, "almanah_ui_manager"));
 
+       /* Accel */
+       gtk_window_add_accel_group (GTK_WINDOW (main_window),
+                                   gtk_ui_manager_get_accel_group (manager));
+
        /* Allow drag the window using the toolbar */
        gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (toolbar)), 
GTK_STYLE_CLASS_MENUBAR);
        gtk_toolbar_set_icon_size (toolbar, GTK_ICON_SIZE_MENU);
diff --git a/src/widgets/entry-tags-area.c b/src/widgets/entry-tags-area.c
index 6fbe61a..64179e5 100644
--- a/src/widgets/entry-tags-area.c
+++ b/src/widgets/entry-tags-area.c
@@ -98,6 +98,7 @@ almanah_entry_tags_area_init (AlmanahEntryTagsArea *self)
        /* The tag entry widget */
        self->priv->tag_entry = g_object_new (ALMANAH_TYPE_TAG_ENTRY, NULL);
        gtk_entry_set_text (GTK_ENTRY (self->priv->tag_entry), _("add tag"));
+       gtk_widget_set_tooltip_text (GTK_WIDGET (self->priv->tag_entry), _("Write the tag and press enter to 
save it"));
        gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->priv->tag_entry));
        g_signal_connect (self->priv->tag_entry, "activate", G_CALLBACK (tag_entry_activate_cb), self);
 }
diff --git a/src/widgets/tag-accessible.c b/src/widgets/tag-accessible.c
new file mode 100644
index 0000000..cda2918
--- /dev/null
+++ b/src/widgets/tag-accessible.c
@@ -0,0 +1,168 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Álvaro Peña 2013 <alvaropg gmail com>
+ *
+ * Almanah is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "tag-accessible.h"
+#include "tag.h"
+
+struct _AlmanahTagAccessiblePrivate
+{
+        gint test;
+};
+
+static void  almanah_tag_accessible_initialize                    (AtkObject *obj, gpointer data);
+
+static const gchar* almanah_tag_accessible_get_name               (AtkObject *accessible);
+
+static void  almanah_tag_accessible_atk_action_iface_init         (AtkActionIface *iface);
+gboolean     almanah_tag_accessible_atk_action_do_action          (AtkAction *action, gint i);
+gint         almanah_tag_accessible_atk_action_get_n_actions      (AtkAction *action);
+const gchar* almanah_tag_accessible_atk_action_get_description    (AtkAction *action, gint i);
+const gchar* almanah_tag_accessible_atk_action_get_name           (AtkAction *action, gint i);
+const gchar* almanah_tag_accessible_atk_action_get_keybinding     (AtkAction *action, gint i);
+gboolean     almanah_tag_accessible_atk_action_set_description    (AtkAction *action, gint i, const gchar 
*desc);
+const gchar* almanah_tag_accessible_atk_action_get_localized_name (AtkAction *action, gint i);
+
+G_DEFINE_TYPE_WITH_CODE (AlmanahTagAccessible, almanah_tag_accessible, GTK_TYPE_WIDGET_ACCESSIBLE,
+                        G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, 
almanah_tag_accessible_atk_action_iface_init))
+
+static void
+almanah_tag_accessible_class_init (AlmanahTagAccessibleClass *klass)
+{
+        AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+        g_type_class_add_private (klass, sizeof (AlmanahTagAccessiblePrivate));
+
+       class->get_name = almanah_tag_accessible_get_name;
+        class->initialize = almanah_tag_accessible_initialize;
+}
+
+static void
+almanah_tag_accessible_init (AlmanahTagAccessible *self)
+{
+}
+
+static void
+almanah_tag_accessible_initialize (AtkObject *obj, gpointer data)
+{
+        GtkWidget  *widget;
+
+        ATK_OBJECT_CLASS (almanah_tag_accessible_parent_class)->initialize (obj, data);
+
+        obj->role = ATK_ROLE_DRAWING_AREA;
+}
+
+/* Code adapted from gtklabelaccessible in GTK+ project */
+static const gchar*
+almanah_tag_accessible_get_name (AtkObject *accessible)
+{
+       const gchar *name;
+
+       g_return_val_if_fail (ALMANAH_IS_TAG_ACCESSIBLE (accessible), NULL);
+
+       name = ATK_OBJECT_CLASS (almanah_tag_accessible_parent_class)->get_name (accessible);
+       if (name != NULL)
+               return name;
+       else {
+               /* Get the text on the tag */
+               GtkWidget *widget;
+
+               widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+               g_return_val_if_fail (widget != NULL, NULL);
+               g_return_val_if_fail (ALMANAH_IS_TAG (widget), NULL);
+
+               return almanah_tag_get_tag (ALMANAH_TAG (widget));
+       }
+}
+
+static void
+almanah_tag_accessible_atk_action_iface_init (AtkActionIface *iface)
+{
+       iface->do_action = almanah_tag_accessible_atk_action_do_action;
+       iface->get_n_actions = almanah_tag_accessible_atk_action_get_n_actions;
+       iface->get_description = almanah_tag_accessible_atk_action_get_description;
+       iface->get_name = almanah_tag_accessible_atk_action_get_name;
+       iface->get_keybinding = almanah_tag_accessible_atk_action_get_keybinding;
+       iface->set_description = almanah_tag_accessible_atk_action_set_description;
+       iface->get_localized_name = almanah_tag_accessible_atk_action_get_localized_name;
+}
+
+gboolean
+almanah_tag_accessible_atk_action_do_action (AtkAction *action, gint i)
+{
+        GtkWidget *widget;
+
+        widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+        g_return_val_if_fail (widget != NULL, FALSE);
+
+       if (i == 0) {
+               almanah_tag_remove (ALMANAH_TAG (widget));
+               return TRUE;
+       } else
+               return FALSE;
+}
+
+gint
+almanah_tag_accessible_atk_action_get_n_actions (AtkAction *action)
+{
+       return 1;
+}
+
+const gchar*
+almanah_tag_accessible_atk_action_get_description (AtkAction *action, gint i)
+{
+       if (i == 0)
+               return "Remove the tag from the entry";
+       else
+               return NULL;
+}
+
+const gchar*
+almanah_tag_accessible_atk_action_get_name (AtkAction *action, gint i)
+{
+       if (i == 0)
+               return "remove";
+       else
+               return NULL;
+}
+
+const gchar*
+almanah_tag_accessible_atk_action_get_keybinding (AtkAction *action, gint i)
+{
+       if (i == 0)
+               return "R;;";
+       else
+               return NULL;
+}
+
+gboolean
+almanah_tag_accessible_atk_action_set_description (AtkAction *action, gint i, const gchar *desc)
+{
+       return FALSE;
+}
+
+const gchar*
+almanah_tag_accessible_atk_action_get_localized_name (AtkAction *action, gint i)
+{
+       if (i == 0)
+               return _("Remove the tag from the entry");
+       else
+               return NULL;
+}
diff --git a/src/widgets/tag-accessible.h b/src/widgets/tag-accessible.h
new file mode 100644
index 0000000..30efc3d
--- /dev/null
+++ b/src/widgets/tag-accessible.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Álvaro Peña 2013 <alvaropg gmail com>
+ *
+ * Almanah is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ALMANAH_TAG_ACCESSIBLE_H
+#define ALMANAH_TAG_ACCESSIBLE_H
+
+#include <gtk/gtk.h>
+#include <gtk/gtk-a11y.h>
+
+G_BEGIN_DECLS
+
+#define ALMANAH_TYPE_TAG_ACCESSIBLE         (almanah_tag_accessible_get_type ())
+#define ALMANAH_TAG_ACCESSIBLE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), ALMANAH_TYPE_TAG_ACCESSIBLE, 
AlmanahTagAccessible))
+#define ALMANAH_TAG_ACCESSIBLE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), ALMANAH_TYPE_TAG_ACCESSIBLE, 
AlmanahTagAccessibleClass))
+#define ALMANAH_IS_TAG_ACCESSIBLE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), ALMANAH_TYPE_TAG_ACCESSIBLE))
+#define ALMANAH_IS_TAG_ACCESSIBLE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), ALMANAH_TYPE_TAG_ACCESSIBLE))
+#define ALMANAH_TAG_ACCESSIBLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ALMANAH_TYPE_TAG_ACCESSIBLE, 
AlmanahTagAccessibleClass))
+
+typedef struct _AlmanahTagAccessiblePrivate AlmanahTagAccessiblePrivate;
+
+typedef struct {
+       GtkWidgetAccessible parent;
+
+       AlmanahTagAccessiblePrivate *priv;
+} AlmanahTagAccessible;
+
+typedef struct {
+       GtkWidgetAccessibleClass parent;
+} AlmanahTagAccessibleClass;
+
+GType almanah_tag_accessible_get_type  (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* !ALMANAH_TAG_ACCESSIBLE_H */
diff --git a/src/widgets/tag-entry.c b/src/widgets/tag-entry.c
index 307b6b7..a5f1606 100644
--- a/src/widgets/tag-entry.c
+++ b/src/widgets/tag-entry.c
@@ -10,11 +10,11 @@
  *
  * Almanah is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Almanah.  If not, see <http://www.gnu.org/licenses/>.
+ * along with Almanah. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <glib/gi18n.h>
@@ -24,124 +24,128 @@
 #include "storage-manager.h"
 
 enum {
-        PROP_STORAGE_MANAGER = 1
+       PROP_STORAGE_MANAGER = 1
 };
 
 struct _AlmanahTagEntryPrivate {
-        GtkListStore *tags_store;
-        AlmanahStorageManager *storage_manager;
+       GtkListStore *tags_store;
+       AlmanahStorageManager *storage_manager;
 };
 
-static void almanah_tag_entry_get_property        (GObject *object, guint property_id, GValue *value, 
GParamSpec *pspec);
-static void almanah_tag_entry_set_property        (GObject *object, guint property_id, const GValue *value, 
GParamSpec *pspec);
-static void almanah_tag_entry_finalize            (GObject *object);
-static void almanah_tag_entry_update_tags         (AlmanahTagEntry *tag_entry);
+static void almanah_tag_entry_get_property       (GObject *object, guint property_id, GValue *value, 
GParamSpec *pspec);
+static void almanah_tag_entry_set_property       (GObject *object, guint property_id, const GValue *value, 
GParamSpec *pspec);
+static void almanah_tag_entry_finalize           (GObject *object);
+static void almanah_tag_entry_update_tags        (AlmanahTagEntry *tag_entry);
 static void almanah_tag_entry_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural);
-gboolean    almanah_tag_entry_focus_out_event     (GtkWidget *self, GdkEventFocus *event);
-gboolean    almanah_tag_entry_focus_in_event      (GtkWidget *self, GdkEventFocus *event);
-gboolean    almanah_tag_entry_match_selected      (GtkEntryCompletion *widget, GtkTreeModel *model, 
GtkTreeIter *iter, AlmanahTagEntry *self);
+gboolean    almanah_tag_entry_focus_out_event    (GtkWidget *self, GdkEventFocus *event);
+gboolean    almanah_tag_entry_focus_in_event     (GtkWidget *self, GdkEventFocus *event);
+gboolean    almanah_tag_entry_match_selected     (GtkEntryCompletion *widget, GtkTreeModel *model, 
GtkTreeIter *iter, AlmanahTagEntry *self);
 
 G_DEFINE_TYPE (AlmanahTagEntry, almanah_tag_entry, GTK_TYPE_ENTRY)
 
 static void
 almanah_tag_entry_class_init (AlmanahTagEntryClass *klass)
 {
-        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+       GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
        GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
 
-        g_type_class_add_private (klass, sizeof (AlmanahTagEntryPrivate));
+       g_type_class_add_private (klass, sizeof (AlmanahTagEntryPrivate));
 
-        gobject_class->get_property = almanah_tag_entry_get_property;
-        gobject_class->set_property = almanah_tag_entry_set_property;
-        gobject_class->finalize = almanah_tag_entry_finalize;
+       gobject_class->get_property = almanah_tag_entry_get_property;
+       gobject_class->set_property = almanah_tag_entry_set_property;
+       gobject_class->finalize = almanah_tag_entry_finalize;
 
        gtkwidget_class->focus_out_event = almanah_tag_entry_focus_out_event;
        gtkwidget_class->focus_in_event = almanah_tag_entry_focus_in_event;
        gtkwidget_class->get_preferred_width = almanah_tag_entry_get_preferred_width;
 
-        g_object_class_install_property (gobject_class, PROP_STORAGE_MANAGER,
-                                        g_param_spec_object ("storage-manager",
-                                                             "Storage manager", "The storage manager whose 
entries should be listed.",
-                                                             ALMANAH_TYPE_STORAGE_MANAGER,
-                                                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+       g_object_class_install_property (gobject_class, PROP_STORAGE_MANAGER,
+                                        g_param_spec_object ("storage-manager",
+                                                             "Storage manager", "The storage manager whose 
entries should be listed.",
+                                                             ALMANAH_TYPE_STORAGE_MANAGER,
+                                                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
 almanah_tag_entry_init (AlmanahTagEntry *self)
 {
-        GtkEntryCompletion *completion;
+       GtkEntryCompletion *completion;
+       AtkObject *self_atk_object;
 
        self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_TAG_ENTRY, AlmanahTagEntryPrivate);
 
-        self->priv->tags_store = gtk_list_store_new (1, G_TYPE_STRING);
-        completion = gtk_entry_completion_new ();
-        gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (self->priv->tags_store));
-        gtk_entry_completion_set_text_column (completion, 0);
-        gtk_entry_set_completion (GTK_ENTRY (self), completion);
+       self->priv->tags_store = gtk_list_store_new (1, G_TYPE_STRING);
+       completion = gtk_entry_completion_new ();
+       gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (self->priv->tags_store));
+       gtk_entry_completion_set_text_column (completion, 0);
+       gtk_entry_set_completion (GTK_ENTRY (self), completion);
        g_signal_connect (completion, "match-selected", G_CALLBACK (almanah_tag_entry_match_selected), self);
+
+       self_atk_object = gtk_widget_get_accessible (GTK_WIDGET (self));
+       atk_object_set_name (self_atk_object, _("Tag entry"));
 }
 
 static void
 almanah_tag_entry_finalize (GObject *object)
 {
-        AlmanahTagEntryPrivate *priv = ALMANAH_TAG_ENTRY (object)->priv;
+       AlmanahTagEntryPrivate *priv = ALMANAH_TAG_ENTRY (object)->priv;
 
-        g_clear_object (&priv->storage_manager);
+       g_clear_object (&priv->storage_manager);
 
-        G_OBJECT_CLASS (almanah_tag_entry_parent_class)->finalize (object);
+       G_OBJECT_CLASS (almanah_tag_entry_parent_class)->finalize (object);
 }
 
 static void
 almanah_tag_entry_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
 {
-        AlmanahTagEntryPrivate *priv = ALMANAH_TAG_ENTRY (object)->priv;
-
-        switch (property_id) {
-                case PROP_STORAGE_MANAGER:
-                        g_value_set_object (value, priv->storage_manager);
-                        break;
-                default:
-                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-                        break;
-        }
+       AlmanahTagEntryPrivate *priv = ALMANAH_TAG_ENTRY (object)->priv;
+
+       switch (property_id) {
+       case PROP_STORAGE_MANAGER:
+               g_value_set_object (value, priv->storage_manager);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+               break;
+       }
 }
 
 static void
 almanah_tag_entry_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
-        AlmanahTagEntryPrivate *priv = ALMANAH_TAG_ENTRY (object)->priv;
-
-        switch (property_id) {
-                case PROP_STORAGE_MANAGER:
-                        g_clear_object (&priv->storage_manager);
-                        priv->storage_manager = ALMANAH_STORAGE_MANAGER (g_value_get_object (value));
-                        g_object_ref (priv->storage_manager);
-                       almanah_tag_entry_update_tags (ALMANAH_TAG_ENTRY (object));
-                        break;
-                default:
-                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-                        break;
-        }        
+       AlmanahTagEntryPrivate *priv = ALMANAH_TAG_ENTRY (object)->priv;
+
+       switch (property_id) {
+       case PROP_STORAGE_MANAGER:
+               g_clear_object (&priv->storage_manager);
+               priv->storage_manager = ALMANAH_STORAGE_MANAGER (g_value_get_object (value));
+               g_object_ref (priv->storage_manager);
+               almanah_tag_entry_update_tags (ALMANAH_TAG_ENTRY (object));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+               break;
+       }
 }
 
 static void
 almanah_tag_entry_update_tags (AlmanahTagEntry *tag_entry)
 {
-        GList *tags;
-        GtkTreeIter iter;
-        AlmanahTagEntryPrivate *priv = tag_entry->priv;
+       GList *tags;
+       GtkTreeIter iter;
+       AlmanahTagEntryPrivate *priv = tag_entry->priv;
 
-        gtk_list_store_clear (priv->tags_store);
-        tags = almanah_storage_manager_get_tags (priv->storage_manager);
-        while (tags) {
-                gtk_list_store_append (priv->tags_store, &iter);
-                gtk_list_store_set (priv->tags_store, &iter, 0, tags->data, -1);
+       gtk_list_store_clear (priv->tags_store);
+       tags = almanah_storage_manager_get_tags (priv->storage_manager);
+       while (tags) {
+               gtk_list_store_append (priv->tags_store, &iter);
+               gtk_list_store_set (priv->tags_store, &iter, 0, tags->data, -1);
 
-                tags = g_list_next (tags);
-        }
+               tags = g_list_next (tags);
+       }
 
-        if (tags)
-                g_list_free (tags);
+       if (tags)
+               g_list_free (tags);
 }
 
 static void
@@ -188,12 +192,12 @@ almanah_tag_entry_match_selected (GtkEntryCompletion *widget, GtkTreeModel *mode
 void
 almanah_tag_entry_set_storage_manager (AlmanahTagEntry *tag_entry, AlmanahStorageManager *storage_manager)
 {
-        GValue storage_value = G_VALUE_INIT;
+       GValue storage_value = G_VALUE_INIT;
 
-        g_return_if_fail (ALMANAH_IS_TAG_ENTRY (tag_entry));
-        g_return_if_fail (ALMANAH_IS_STORAGE_MANAGER (storage_manager));
+       g_return_if_fail (ALMANAH_IS_TAG_ENTRY (tag_entry));
+       g_return_if_fail (ALMANAH_IS_STORAGE_MANAGER (storage_manager));
 
-        g_value_init (&storage_value, G_TYPE_OBJECT);
+       g_value_init (&storage_value, G_TYPE_OBJECT);
        g_value_set_object (&storage_value, storage_manager);
        g_object_set_property (G_OBJECT (tag_entry), "storage-manager", &storage_value);
        g_value_unset (&storage_value);
diff --git a/src/widgets/tag.c b/src/widgets/tag.c
index 59e76e8..6a03de8 100644
--- a/src/widgets/tag.c
+++ b/src/widgets/tag.c
@@ -22,6 +22,7 @@
 #include <math.h>
 
 #include "tag.h"
+#include "tag-accessible.h"
 
 #define PADDING_TOP    1
 #define PADDING_BOTTOM 1
@@ -106,6 +107,8 @@ almanah_tag_class_init (AlmanahTagClass *klass)
                                                   0, NULL, NULL,
                                                   g_cclosure_marshal_VOID__VOID,
                                                   G_TYPE_NONE, 0);
+
+       gtk_widget_class_set_accessible_type (widget_class, ALMANAH_TYPE_TAG_ACCESSIBLE);
 }
 
 static void
@@ -114,7 +117,10 @@ almanah_tag_init (AlmanahTag *self)
        self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_TAG, AlmanahTagPrivate);
        g_signal_connect (G_OBJECT (self), "draw", G_CALLBACK (almanah_tag_draw), NULL);
 
-       gtk_widget_add_events (GTK_WIDGET  (self), GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | 
GDK_BUTTON_RELEASE_MASK);
+       gtk_widget_add_events (GTK_WIDGET  (self),
+                              GDK_POINTER_MOTION_MASK
+                              | GDK_BUTTON_PRESS_MASK
+                              | GDK_BUTTON_RELEASE_MASK);
 
        gdk_rgba_parse (&self->priv->text_color, "#936835");
        gdk_rgba_parse (&self->priv->strock_color, "#ECB447");
@@ -125,6 +131,8 @@ almanah_tag_init (AlmanahTag *self)
 
        self->priv->close_highlighted = FALSE;
        self->priv->close_pressed = FALSE;
+
+       gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
 }
 
 static void
@@ -286,8 +294,8 @@ almanah_tag_draw (GtkWidget *widget, cairo_t *cr, gpointer data)
 
        /* Get the tag dimensions */
        gtk_widget_get_preferred_width (widget, &width, NULL);
-       width = width - SHADOW_RIGHT;
        gtk_widget_get_preferred_height (widget, &height, NULL);
+       width = width - SHADOW_RIGHT;
        height = height - SHADOW_BOTTOM;
 
        /* Some coordinates */
@@ -384,6 +392,14 @@ almanah_tag_draw (GtkWidget *widget, cairo_t *cr, gpointer data)
        cairo_line_to (cr, priv->close_x, y_origin + middle_height + (CLOSE_BUTTON / 2));
        cairo_stroke (cr);
 
+       /* Focus */
+       if (gtk_widget_has_focus (widget))
+               gtk_render_focus (gtk_widget_get_style_context (widget),
+                                 cr,
+                                 0, 0,
+                                 gtk_widget_get_allocated_width (widget),
+                                 gtk_widget_get_allocated_height (widget));
+
        return FALSE;
 }
 
@@ -412,7 +428,6 @@ almanah_tag_new (const gchar *tag)
                                         NULL));
 }
 
-
 const gchar *
 almanah_tag_get_tag (AlmanahTag *tag_widget)
 {
@@ -420,3 +435,11 @@ almanah_tag_get_tag (AlmanahTag *tag_widget)
 
        return tag_widget->priv->tag;
 }
+
+void
+almanah_tag_remove (AlmanahTag *tag_widget)
+{
+       g_return_val_if_fail (ALMANAH_IS_TAG (tag_widget), NULL);
+
+       g_signal_emit (tag_widget, tag_signals[SIGNAL_REMOVE], 0);
+}
diff --git a/src/widgets/tag.h b/src/widgets/tag.h
index 8311626..3628230 100644
--- a/src/widgets/tag.h
+++ b/src/widgets/tag.h
@@ -42,9 +42,10 @@ typedef struct {
        GtkDrawingAreaClass parent;
 } AlmanahTagClass;
 
-GType      almanah_tag_get_type  (void) G_GNUC_CONST;
-GtkWidget *almanah_tag_new       (const gchar *tag);
-const gchar *almanah_tag_get_tag (AlmanahTag *tag_widget);
+GType        almanah_tag_get_type (void) G_GNUC_CONST;
+GtkWidget   *almanah_tag_new      (const gchar *tag);
+const gchar *almanah_tag_get_tag  (AlmanahTag *tag_widget);
+void         almanah_tag_remove   (AlmanahTag *tag_widget);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]