Fixed bug #517761, Collection match rules not working for attributes.
[platform/core/uifw/at-spi2-atk.git] / libspi / hyperlink.c
index 36b538d..6d6bf5d 100644 (file)
@@ -2,7 +2,8 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,6 +26,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <libspi/hyperlink.h>
+#include <libspi/action.h>
 #include <libspi/accessible.h>
 
 /* Static function declarations */
@@ -57,7 +59,7 @@ impl_isValid (PortableServer_Servant _servant,
 BONOBO_TYPE_FUNC_FULL (SpiHyperlink,
                       Accessibility_Hyperlink,
                       SPI_TYPE_BASE,
-                      spi_hyperlink);
+                      spi_hyperlink)
 
 
 static void
@@ -83,28 +85,57 @@ spi_hyperlink_init (SpiHyperlink *hyperlink)
 
 
 SpiHyperlink *
-spi_hyperlink_new (AtkObject *object)
+spi_hyperlink_new (AtkHyperlink *object)
 {
   SpiHyperlink *new_hyperlink = g_object_new (
          SPI_HYPERLINK_TYPE, NULL);
 
-  spi_base_construct (SPI_BASE (new_hyperlink), object);
+  spi_base_construct (SPI_BASE (new_hyperlink), G_OBJECT(object));
 
+  /* 
+   * some hyperlinks are actionable... this is an ATK convention 
+   * that seems convenient though possibly poorly documented or unintended.
+   */
+  if (ATK_IS_ACTION (object))
+    {
+      /* 
+       * NOTE: we don't cast 'object' to ATK_OBJECT in the call to 
+       * spi_action_interface_new(), because of the above convention, 
+       * even though it means we may be violating the func prototype.
+       * See discussion in bugzilla bug #120659.
+       * !!!
+       * IMPORTANT! The 'AtkObject' typecast, instead of the cast macro,
+       * is used below, because 'object' may NOT really be an AtkObject;
+       * it will be cast back to a G_OBJECT inside spi_action_interface_new
+       * before use, so this is OK though very ropey coding style.
+       */
+
+       /* Don't aggregate action twice... if this is from AtkHyperlinkImpl */
+       if (!bonobo_object_query_interface (bonobo_object (new_hyperlink), "IDL:Accessibility/Action:1.0",
+                                           NULL))
+           
+           bonobo_object_add_interface (bonobo_object (new_hyperlink),
+                                        BONOBO_OBJECT (spi_action_interface_new ((AtkObject *) object)));
+    }
   return new_hyperlink;
 }
 
-
 static AtkHyperlink *
 get_hyperlink_from_servant (PortableServer_Servant servant)
 {
   SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
 
-  if (!object)
-    {
+  g_return_val_if_fail (object != NULL, NULL);
+  if (ATK_IS_HYPERLINK(object->gobj)) 
+  {
+      return ATK_HYPERLINK (object->gobj);
+  }
+  else if (ATK_IS_HYPERLINK_IMPL(object->gobj))
+  {
+      return atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (object->gobj));
+  }
+  else
       return NULL;
-    }
-
-  return ATK_HYPERLINK (object->atko);
 }
 
 
@@ -116,7 +147,7 @@ impl__get_n_anchors (PortableServer_Servant servant,
 
   g_return_val_if_fail (link != NULL, 0);
 
-  return (CORBA_short) atk_hyperlink_get_n_anchors (link);
+  return atk_hyperlink_get_n_anchors (link);
 }
 
 
@@ -128,7 +159,7 @@ impl__get_startIndex (PortableServer_Servant servant,
 
   g_return_val_if_fail (link != NULL, -1);
 
-  return (CORBA_long) atk_hyperlink_get_start_index (link);
+  return atk_hyperlink_get_start_index (link);
 }
 
 
@@ -140,7 +171,7 @@ impl__get_endIndex (PortableServer_Servant servant,
 
   g_return_val_if_fail (link != NULL, -1);
 
-  return (CORBA_long) atk_hyperlink_get_end_index (link);
+  return atk_hyperlink_get_end_index (link);
 }
 
 
@@ -154,7 +185,7 @@ impl_getURI (PortableServer_Servant servant,
 
   g_return_val_if_fail (link != NULL, CORBA_string_dup (""));
 
-  uri = atk_hyperlink_get_uri (link, (gint) i);
+  uri = atk_hyperlink_get_uri (link, i);
   if (uri)
     {
       rv = CORBA_string_dup (uri);
@@ -177,7 +208,7 @@ impl_getObject (PortableServer_Servant servant,
 
   g_return_val_if_fail (link != NULL, CORBA_OBJECT_NIL);
 
-  atk_object = atk_hyperlink_get_object (link, (gint) i);
+  atk_object = atk_hyperlink_get_object (link, i);
 
   return spi_accessible_new_return (atk_object, FALSE, ev);
 }
@@ -191,6 +222,6 @@ impl_isValid (PortableServer_Servant servant,
 
   g_return_val_if_fail (link != NULL, TRUE);
 
-  return (CORBA_boolean) atk_hyperlink_is_valid (link);
+  return atk_hyperlink_is_valid (link);
 }