[l10n] Updated Catalan (Valencian) translation
[platform/upstream/atk.git] / atk / atkrelation.c
old mode 100755 (executable)
new mode 100644 (file)
index edb3a6e..6dcb1c4
  * Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
+
 #include <string.h>
 #include <glib-object.h>
-#include "atkobject.h"
-#include "atkrelation.h"
-#include "atk-enum-types.h"
+#include "atk.h"
+
+/**
+ * SECTION:atkrelation
+ * @Short_description: An object used to describe a relation between a
+ *  object and one or more other objects.
+ * @Title:AtkRelation
+ *
+ * An AtkRelation describes a relation between an object and one or
+ * more other objects. The actual relations that an object has with
+ * other objects are defined as an AtkRelationSet, which is a set of
+ * AtkRelations.
+ */
+enum {
+  PROP_0,
 
-GPtrArray *extra_names = NULL;
+  PROP_RELATION_TYPE,
+  PROP_TARGET,
+  PROP_LAST
+};
 
-GObjectClass *parent_class;
+static GPtrArray *extra_names = NULL;
+
+static gpointer parent_class = NULL;
   
-static void atk_relation_class_init (AtkRelationClass *klass);
-static void atk_relation_finalize   (GObject          *object);
+static void atk_relation_class_init   (AtkRelationClass *klass);
+static void atk_relation_finalize     (GObject          *object);
+static void atk_relation_set_property (GObject          *object,
+                                       guint            prop_id,
+                                       const GValue     *value,
+                                       GParamSpec       *pspec);
+static void atk_relation_get_property (GObject          *object,
+                                       guint            prop_id,
+                                       GValue           *value,
+                                       GParamSpec       *pspec);
+
+static GPtrArray* atk_relation_get_ptr_array_from_value_array (GValueArray *array);
+static GValueArray* atk_relation_get_value_array_from_ptr_array (GPtrArray *array);
 
 GType
 atk_relation_get_type (void)
@@ -62,6 +92,25 @@ atk_relation_class_init (AtkRelationClass *klass)
   parent_class = g_type_class_peek_parent (klass);
   
   gobject_class->finalize = atk_relation_finalize;
+  gobject_class->set_property = atk_relation_set_property;
+  gobject_class->get_property = atk_relation_get_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_RELATION_TYPE,
+                                   g_param_spec_enum ("relation_type",
+                                                      "Relation Type",
+                                                      "The type of the relation",
+                                                      ATK_TYPE_RELATION_TYPE,
+                                                      ATK_RELATION_NULL,
+                                                      G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                   PROP_TARGET,
+                                   g_param_spec_value_array ("target",
+                                                             "Target",
+                                                             "An array of the targets for the relation",
+                                                             NULL,
+
+                                                             G_PARAM_READWRITE));
 }
 
 /**
@@ -69,7 +118,7 @@ atk_relation_class_init (AtkRelationClass *klass)
  * @name: a name string
  *
  * Associate @name with a new #AtkRelationType
- *
  * Returns: an #AtkRelationType associated with @name
  **/
 AtkRelationType
@@ -92,12 +141,12 @@ atk_relation_type_register (const gchar *name)
  *
  * Returns: the string describing the AtkRelationType
  */
-G_CONST_RETURN gchar*
+const gchar*
 atk_relation_type_get_name (AtkRelationType type)
 {
   GTypeClass *type_class;
   GEnumValue *value;
-  gchar *name = NULL;
+  const gchar *name = NULL;
 
   type_class = g_type_class_ref (ATK_TYPE_RELATION_TYPE);
   g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
@@ -179,13 +228,14 @@ atk_relation_type_for_name (const gchar *name)
 
 /**
  * atk_relation_new:
- * @targets: an array of pointers to #AtkObjects  
+ * @targets: (array length=n_targets): an array of pointers to
+ *  #AtkObjects
  * @n_targets: number of #AtkObjects pointed to by @targets
  * @relationship: an #AtkRelationType with which to create the new
  *  #AtkRelation
  *
  * Create a new relation for the specified key and the specified list
- * of targets.
+ * of targets.  See also atk_object_add_relationship().
  *
  * Returns: a pointer to a new #AtkRelation
  **/
@@ -196,23 +246,28 @@ atk_relation_new (AtkObject       **targets,
 {
   AtkRelation *relation;
   int         i;
-  GPtrArray      *array;
+  GValueArray *array;
+  GValue      *value;
 
   g_return_val_if_fail (targets != NULL, NULL);
 
-  relation = g_object_new (ATK_TYPE_RELATION, NULL);
-  array = g_ptr_array_sized_new (n_targets);
+  array = g_value_array_new (n_targets);
   for (i = 0; i < n_targets; i++)
   {
-    /*
-     * Add a reference to AtkObject being added to a relation
-     */
-    g_object_ref (targets[i]);
-    g_ptr_array_add (array, targets[i]);
+    value = g_new0 (GValue, 1);
+    g_value_init (value, ATK_TYPE_OBJECT);
+    g_value_set_object (value, targets[i]);
+    array = g_value_array_append (array, value);
+    g_value_unset (value);
+    g_free (value);
   }
   
-  relation->target = array;
-  relation->relationship = relationship;
+  relation =  g_object_new (ATK_TYPE_RELATION, 
+                            "relation_type", relationship,
+                            "target", array,
+                            NULL);
+
+  g_value_array_free (array);
 
   return relation;
 }
@@ -239,17 +294,87 @@ atk_relation_get_relation_type (AtkRelation *relation)
  *
  * Gets the target list of @relation
  *
- * Returns: the target list of @relation
+ * Returns: (transfer none) (element-type Atk.Object): the target list of @relation
  **/
 GPtrArray*
 atk_relation_get_target (AtkRelation *relation)
 {
-  g_return_val_if_fail (ATK_IS_RELATION (relation), FALSE);
+  g_return_val_if_fail (ATK_IS_RELATION (relation), NULL);
 
   return relation->target;
 }
 
 static void
+delete_object_while_in_relation (gpointer callback_data,
+                                 GObject *where_the_object_was)
+{
+  GPtrArray *array;
+
+  g_assert (callback_data != NULL);
+
+  array = callback_data;
+  g_ptr_array_remove (array, where_the_object_was);
+}
+
+/**
+ * atk_relation_add_target:
+ * @relation: an #AtkRelation
+ * @target: an #AtkObject
+ *
+ * Adds the specified AtkObject to the target for the relation, if it is
+ * not already present.  See also atk_object_add_relationship().
+ *
+ *
+ * Since: 1.9
+ **/
+void
+atk_relation_add_target (AtkRelation *relation,
+                         AtkObject   *target)
+{
+  guint i;
+
+  g_return_if_fail (ATK_IS_RELATION (relation));
+  g_return_if_fail (ATK_IS_OBJECT (target));
+
+  /* first check if target occurs in array ... */
+  for (i = 0; i < relation->target->len; i++)
+    if (g_ptr_array_index(relation->target, i) == target)
+      return;
+
+  g_ptr_array_add (relation->target, target);
+  g_object_weak_ref (G_OBJECT (target), (GWeakNotify) delete_object_while_in_relation, relation->target);
+}
+
+/**
+ * atk_relation_remove_target:
+ * @relation: an #AtkRelation
+ * @target: an #AtkObject
+ *
+ * Remove the specified AtkObject from the target for the relation.
+ *
+ * Returns: TRUE if the removal is successful.
+ **/
+
+gboolean
+atk_relation_remove_target (AtkRelation *relation,
+                            AtkObject *target)
+{
+  gboolean ret = FALSE;
+  GPtrArray *array;
+
+  array = atk_relation_get_target (relation);
+
+  if (array && g_ptr_array_remove (array, target))
+    {
+      g_object_weak_unref (G_OBJECT (target),
+                           (GWeakNotify) delete_object_while_in_relation,
+                           relation->target);
+      ret = TRUE;
+    }
+  return ret;
+}
+
+static void
 atk_relation_finalize (GObject *object)
 {
   AtkRelation        *relation;
@@ -264,13 +389,113 @@ atk_relation_finalize (GObject *object)
 
     for (i = 0; i < relation->target->len; i++)
     {
-      /*
-       * Remove a reference to AtkObject being removed from a relation
-       */
-      g_object_unref (g_ptr_array_index (relation->target, i));
+      g_object_weak_unref (G_OBJECT (g_ptr_array_index (relation->target, i)),
+                           (GWeakNotify) delete_object_while_in_relation, 
+                           relation->target);
     }
     g_ptr_array_free (relation->target, TRUE);
   } 
 
-  parent_class->finalize (object);
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void 
+atk_relation_set_property (GObject       *object,
+                           guint         prop_id,
+                           const GValue  *value,
+                           GParamSpec    *pspec)
+{
+  AtkRelation *relation;
+  gpointer boxed;
+
+  relation = ATK_RELATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_RELATION_TYPE:
+      relation->relationship = g_value_get_enum (value);
+      break; 
+    case PROP_TARGET:
+      if (relation->target)
+      {
+        gint i;
+
+        for (i = 0; i < relation->target->len; i++)
+        {
+          g_object_weak_unref (G_OBJECT (g_ptr_array_index (relation->target, i)),
+                               (GWeakNotify) delete_object_while_in_relation,
+                               relation->target);
+        }
+        g_ptr_array_free (relation->target, TRUE);
+      }
+      boxed = g_value_get_boxed (value);
+      relation->target = atk_relation_get_ptr_array_from_value_array ( (GValueArray *) boxed);
+      break; 
+    default:
+      break;
+    }  
+}
+
+static void
+atk_relation_get_property (GObject    *object,
+                           guint      prop_id,
+                           GValue     *value,
+                           GParamSpec *pspec)
+{
+  AtkRelation *relation;
+  GValueArray *array;
+
+  relation = ATK_RELATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_RELATION_TYPE:
+      g_value_set_enum (value, relation->relationship);
+      break;
+    case PROP_TARGET:
+      array = atk_relation_get_value_array_from_ptr_array (relation->target);
+      g_value_set_boxed (value, array);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }  
+}
+
+static GPtrArray*
+atk_relation_get_ptr_array_from_value_array (GValueArray *array)
+{
+  gint i;
+  GPtrArray *return_array;
+  GValue *value;
+  GObject *obj;
+
+  return_array = g_ptr_array_sized_new (array->n_values);
+  for (i = 0; i < array->n_values; i++)
+    {
+      value = g_value_array_get_nth (array, i);
+      obj = g_value_get_object (value);
+      g_ptr_array_add (return_array, obj);
+      g_object_weak_ref (obj, (GWeakNotify) delete_object_while_in_relation, return_array);
+    }
+      
+  return return_array;
+}
+
+static GValueArray*
+atk_relation_get_value_array_from_ptr_array (GPtrArray *array)
+{
+  int         i;
+  GValueArray *return_array;
+  GValue      *value;
+
+  return_array = g_value_array_new (array->len);
+  for (i = 0; i < array->len; i++)
+    {
+      value = g_new0 (GValue, 1);
+      g_value_init (value, ATK_TYPE_OBJECT);
+      g_value_set_object (value, g_ptr_array_index (array, i));
+      return_array = g_value_array_append (return_array, value);
+    }
+  return return_array;
 }