2007-09-08 Li Yuan <li.yuan@sun.com>
[platform/core/uifw/at-spi2-atk.git] / libspi / hyperlink.c
index b28a589..6d6bf5d 100644 (file)
@@ -26,6 +26,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <libspi/hyperlink.h>
+#include <libspi/action.h>
 #include <libspi/accessible.h>
 
 /* Static function declarations */
@@ -58,7 +59,7 @@ impl_isValid (PortableServer_Servant _servant,
 BONOBO_TYPE_FUNC_FULL (SpiHyperlink,
                       Accessibility_Hyperlink,
                       SPI_TYPE_BASE,
-                      spi_hyperlink);
+                      spi_hyperlink)
 
 
 static void
@@ -91,18 +92,50 @@ spi_hyperlink_new (AtkHyperlink *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));
 
   g_return_val_if_fail (object != NULL, NULL);
-  g_return_val_if_fail (ATK_IS_HYPERLINK(object->gobj), NULL);
-  return ATK_HYPERLINK (object->gobj);
+  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;
 }