Index: glib/poppler-action.cc
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-action.cc,v
retrieving revision 1.9
diff -u -p -r1.9 poppler-action.cc
--- glib/poppler-action.cc	19 May 2006 22:26:03 -0000	1.9
+++ glib/poppler-action.cc	21 May 2006 13:16:19 -0000
@@ -75,117 +75,692 @@ poppler_dest_free (PopplerDest *dest)
 	g_free (dest);
 }
 
-GType
-poppler_action_get_type (void)
+enum
 {
-  static GType our_type = 0;
+        PROP_0,
+        PROP_TYPE,
+        PROP_TITLE,
+        PROP_DEST,
+        PROP_FILE_NAME,
+        PROP_PARAMS,
+        PROP_URI,
+        PROP_NAMED_DEST,
+};
+
+#define ACTION_G_PARAM_FLAGS ((GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))
+
+/* PopplerAction */
+typedef struct _PopplerActionClass PopplerActionClass;
+struct _PopplerActionClass
+{
+        GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerAction, poppler_action, G_TYPE_OBJECT);
+
+static void
+poppler_action_finalize (GObject *object)
+{
+        PopplerAction *action = POPPLER_ACTION (object);
+
+	g_free (action->title);
+}
+
+static void
+poppler_action_get_property (GObject         *object,
+			     guint            prop_id,
+			     GValue          *value,
+			     GParamSpec      *pspec)
+{
+	PopplerAction *action = POPPLER_ACTION (object);
+
+	switch (prop_id) {
+	case PROP_TYPE:
+		g_value_set_enum (value, action->type);
+		break;
+	case PROP_TITLE:
+		g_value_set_string (value, action->title);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+        }
+}
+
+static void
+poppler_action_set_property (GObject         *object,
+                             guint            prop_id,
+                             const GValue    *value,
+                             GParamSpec      *pspec)
+{
+	PopplerAction *action = POPPLER_ACTION (object);
+
+	switch (prop_id) {
+	case PROP_TYPE:
+		action->type = (PopplerActionType) g_value_get_enum (value);
+		break;
+	case PROP_TITLE:
+		g_free (action->title);
+		action->title = g_strdup (g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+        }
+}
+
+
+static void
+poppler_action_class_init (PopplerActionClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = poppler_action_finalize;
+        gobject_class->get_property = poppler_action_get_property;
+        gobject_class->set_property = poppler_action_set_property;
+
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_TYPE,
+                 g_param_spec_enum ("type",
+                                    "Action Type",
+                                    "The type of the action",
+                                    POPPLER_TYPE_ACTION_TYPE,
+                                    POPPLER_ACTION_UNKNOWN,
+                                    ACTION_G_PARAM_FLAGS));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_TITLE,
+                 g_param_spec_string ("title",
+                                      "Action Title",
+                                      "The title of the action",
+                                      NULL,
+                                      ACTION_G_PARAM_FLAGS));
+}
+
+static void
+poppler_action_init (PopplerAction *action)
+{
+        action->title = NULL;
+}
+
+PopplerActionType
+poppler_action_get_action_type (PopplerAction *action)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION (action),
+			      POPPLER_ACTION_UNKNOWN);
+
+	return (PopplerActionType) (action->type);
+}
 
-  if (our_type == 0)
-    our_type = g_boxed_type_register_static ("PopplerAction",
-					     (GBoxedCopyFunc) poppler_action_copy,
-					     (GBoxedFreeFunc) poppler_action_free);
+G_CONST_RETURN gchar *
+poppler_action_get_title (PopplerAction *action)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION (action), NULL);
 
-  return our_type;
+	return action->title;
 }
 
-/**
- * poppler_action_free:
- * @action: a #PopplerAction
- * 
- * Frees @action
- **/
-void
-poppler_action_free (PopplerAction *action)
+
+/* PopplerActionGotoDest */
+typedef struct _PopplerActionGotoDestClass PopplerActionGotoDestClass;
+struct _PopplerActionGotoDestClass
+{
+	PopplerActionClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerActionGotoDest, poppler_action_goto_dest,
+	       POPPLER_TYPE_ACTION);
+
+static void
+poppler_action_goto_dest_finalize (GObject *object)
 {
-	if (action == NULL)
-		return;
+        PopplerActionGotoDest *goto_dest = POPPLER_ACTION_GOTO_DEST (object);
+
+	poppler_dest_free (goto_dest->dest);
+
+	G_OBJECT_CLASS (poppler_action_goto_dest_parent_class)->finalize (object);
+}
 
-	/* Action specific stuff */
-	switch (action->type) {
-	case POPPLER_ACTION_GOTO_DEST:
-		poppler_dest_free (action->goto_dest.dest);
+static void
+poppler_action_goto_dest_get_property (GObject         *object,
+				       guint            prop_id,
+				       GValue          *value,
+				       GParamSpec      *pspec)
+{
+	PopplerActionGotoDest *goto_dest = POPPLER_ACTION_GOTO_DEST (object);
+
+	switch (prop_id) {
+	case PROP_DEST:
+		g_value_set_boxed (value, goto_dest->dest);
 		break;
-	case POPPLER_ACTION_GOTO_REMOTE:
-		poppler_dest_free (action->goto_remote.dest);
-		g_free (action->goto_remote.file_name);
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
-	case POPPLER_ACTION_URI:
-		g_free (action->uri.uri);
+        }
+}
+
+static void
+poppler_action_goto_dest_set_property (GObject         *object,
+				       guint            prop_id,
+				       const GValue    *value,
+				       GParamSpec      *pspec)
+{
+	PopplerActionGotoDest *goto_dest = POPPLER_ACTION_GOTO_DEST (object);
+
+	switch (prop_id) {
+	case PROP_DEST:
+		if (goto_dest->dest)
+			poppler_dest_free (goto_dest->dest);
+
+		{
+			PopplerDest *dest;
+			dest = (PopplerDest *) g_value_get_boxed (value);
+			goto_dest->dest = poppler_dest_copy (dest);
+		}
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+        }
+}
+
+
+static void
+poppler_action_goto_dest_class_init (PopplerActionGotoDestClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = poppler_action_goto_dest_finalize;
+        gobject_class->get_property = poppler_action_goto_dest_get_property;
+        gobject_class->set_property = poppler_action_goto_dest_set_property;
+
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_DEST,
+                 g_param_spec_boxed ("dest",
+				     "Action Destination",
+				     "The destination of the action",
+				     POPPLER_TYPE_DEST,
+				     ACTION_G_PARAM_FLAGS));
+}
+
+static void
+poppler_action_goto_dest_init (PopplerActionGotoDest *goto_dest)
+{
+	goto_dest->dest = NULL;
+}
+
+G_CONST_RETURN PopplerDest *
+poppler_action_goto_dest_get_dest (PopplerActionGotoDest *goto_dest)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_GOTO_DEST (goto_dest), NULL);
+
+	return goto_dest->dest;
+}
+
+
+/* PopplerActionGotoRemote */
+typedef struct _PopplerActionGotoRemoteClass PopplerActionGotoRemoteClass;
+struct _PopplerActionGotoRemoteClass
+{
+	PopplerActionClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerActionGotoRemote, poppler_action_goto_remote,
+	       POPPLER_TYPE_ACTION);
+
+static void
+poppler_action_goto_remote_finalize (GObject *object)
+{
+	PopplerActionGotoRemote *goto_remote;
+	goto_remote = POPPLER_ACTION_GOTO_REMOTE (object);
+
+	g_free (goto_remote->file_name);
+	poppler_dest_free (goto_remote->dest);
+
+	G_OBJECT_CLASS (poppler_action_goto_remote_parent_class)->finalize (object);
+}
+
+static void
+poppler_action_goto_remote_get_property (GObject         *object,
+					 guint            prop_id,
+					 GValue          *value,
+					 GParamSpec      *pspec)
+{
+	PopplerActionGotoRemote *goto_remote;
+	goto_remote = POPPLER_ACTION_GOTO_REMOTE (object);
+
+	switch (prop_id) {
+	case PROP_FILE_NAME:
+		g_value_set_string (value, goto_remote->file_name);
 		break;
-	case POPPLER_ACTION_LAUNCH:
-		g_free (action->launch.file_name);
-		g_free (action->launch.params);
+	case PROP_DEST:
+		g_value_set_boxed (value, goto_remote->dest);
 		break;
-	case POPPLER_ACTION_NAMED:
-		g_free (action->named.named_dest);
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
-	case POPPLER_ACTION_MOVIE:
-		/* TODO */
+        }
+}
+
+static void
+poppler_action_goto_remote_set_property (GObject         *object,
+				       guint            prop_id,
+				       const GValue    *value,
+				       GParamSpec      *pspec)
+{
+	PopplerActionGotoRemote *goto_remote;
+	goto_remote = POPPLER_ACTION_GOTO_REMOTE (object);
+
+	switch (prop_id) {
+	case PROP_FILE_NAME:
+		g_free (goto_remote->file_name);
+		goto_remote->file_name = g_strdup (g_value_get_string (value));
+		break;
+	case PROP_DEST:
+		if (goto_remote->dest)
+			poppler_dest_free (goto_remote->dest);
+
+		{
+			PopplerDest *dest;
+			dest = (PopplerDest *) g_value_get_boxed (value);
+			goto_remote->dest = poppler_dest_copy (dest);
+		}
 		break;
 	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
-	}
-	
-	g_free (action->any.title);
-	g_free (action);
+        }
 }
 
-/**
- * poppler_action_copy:
- * @action: a #PopplerAction
- * 
- * Copies @action, creating an identical #PopplerAction.
- * 
- * Return value: a new action identical to @action
- **/
-PopplerAction *
-poppler_action_copy (PopplerAction *action)
+
+static void
+poppler_action_goto_remote_class_init (PopplerActionGotoRemoteClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = poppler_action_goto_remote_finalize;
+        gobject_class->get_property = poppler_action_goto_remote_get_property;
+        gobject_class->set_property = poppler_action_goto_remote_set_property;
+
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILE_NAME,
+                 g_param_spec_string ("file_name",
+				      "File Name",
+				      "The file name of the destination",
+				      NULL,
+				      ACTION_G_PARAM_FLAGS));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_DEST,
+                 g_param_spec_boxed ("dest",
+				     "Action Destination",
+				     "The destination of the action",
+				     POPPLER_TYPE_DEST,
+				     ACTION_G_PARAM_FLAGS));
+}
+
+static void
+poppler_action_goto_remote_init (PopplerActionGotoRemote *goto_remote)
 {
-	PopplerAction *new_action;
+	goto_remote->file_name = NULL;
+	goto_remote->dest = NULL;
+}
+
+G_CONST_RETURN gchar *
+poppler_action_goto_remote_get_file_name (PopplerActionGotoRemote *goto_remote)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_GOTO_REMOTE (goto_remote), NULL);
+
+	return goto_remote->file_name;
+}
+
+G_CONST_RETURN PopplerDest *
+poppler_action_goto_remote_get_dest (PopplerActionGotoRemote *goto_remote)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_GOTO_REMOTE (goto_remote), NULL);
+
+	return goto_remote->dest;
+}
+
+
+/* PopplerActionLaunch */
+typedef struct _PopplerActionLaunchClass PopplerActionLaunchClass;
+struct _PopplerActionLaunchClass
+{
+	PopplerActionClass parent_class;
+};
 
-	g_return_val_if_fail (action != NULL, NULL);
+G_DEFINE_TYPE (PopplerActionLaunch, poppler_action_launch, POPPLER_TYPE_ACTION);
 
-	/* Do a straight copy of the memory */
-	new_action = g_new0 (PopplerAction, 1);
-	memcpy (new_action, action, sizeof (PopplerAction));
+static void
+poppler_action_launch_finalize (GObject *object)
+{
+	PopplerActionLaunch *launch;
+	launch = POPPLER_ACTION_LAUNCH (object);
 
-	if (action->any.title != NULL)
-		new_action->any.title = g_strdup (action->any.title);
+	g_free (launch->file_name);
+	g_free (launch->params);
+
+	G_OBJECT_CLASS (poppler_action_launch_parent_class)->finalize (object);
+}
 
-	switch (action->type) {
-	case POPPLER_ACTION_GOTO_DEST:
-		new_action->goto_dest.dest = poppler_dest_copy (action->goto_dest.dest);
+static void
+poppler_action_launch_get_property (GObject         *object,
+				    guint            prop_id,
+				    GValue          *value,
+				    GParamSpec      *pspec)
+{
+	PopplerActionLaunch *launch;
+	launch = POPPLER_ACTION_LAUNCH (object);
+
+	switch (prop_id) {
+	case PROP_FILE_NAME:
+		g_value_set_string (value, launch->file_name);
 		break;
-	case POPPLER_ACTION_GOTO_REMOTE:
-		new_action->goto_remote.dest = poppler_dest_copy (action->goto_remote.dest);
-		if (action->goto_remote.file_name)
-			new_action->goto_remote.file_name = g_strdup (action->goto_remote.file_name);
+	case PROP_PARAMS:
+		g_value_set_string (value, launch->params);
 		break;
-	case POPPLER_ACTION_URI:
-		if (action->uri.uri)
-			new_action->uri.uri = g_strdup (action->uri.uri);
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
-	case POPPLER_ACTION_LAUNCH:
-		if (action->launch.file_name)
-			new_action->launch.file_name = g_strdup (action->launch.file_name);
-		if (action->launch.params)
-			new_action->launch.params = g_strdup (action->launch.params);
+        }
+}
+
+static void
+poppler_action_launch_set_property (GObject         *object,
+				    guint            prop_id,
+				    const GValue    *value,
+				    GParamSpec      *pspec)
+{
+	PopplerActionLaunch *launch;
+	launch = POPPLER_ACTION_LAUNCH (object);
+
+	switch (prop_id) {
+	case PROP_FILE_NAME:
+		g_free (launch->file_name);
+		launch->file_name = g_strdup (g_value_get_string (value));
+		break;
+	case PROP_PARAMS:
+		g_free (launch->params);
+		launch->params = g_strdup (g_value_get_string (value));
 		break;
-	case POPPLER_ACTION_NAMED:
-		if (action->named.named_dest)
-			new_action->named.named_dest = g_strdup (action->named.named_dest);
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
-	case POPPLER_ACTION_MOVIE:
-		/* TODO */
+        }
+}
+
+
+static void
+poppler_action_launch_class_init (PopplerActionLaunchClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = poppler_action_launch_finalize;
+        gobject_class->get_property = poppler_action_launch_get_property;
+        gobject_class->set_property = poppler_action_launch_set_property;
+
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILE_NAME,
+                 g_param_spec_string ("file_name",
+				      "File Name",
+				      "The file name of the launch",
+				      NULL,
+				      ACTION_G_PARAM_FLAGS));
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_PARAMS,
+                 g_param_spec_string ("params",
+				      "Parameters",
+				      "The parameters of the action",
+				      NULL,
+				      ACTION_G_PARAM_FLAGS));
+}
+
+static void
+poppler_action_launch_init (PopplerActionLaunch *launch)
+{
+	launch->file_name = NULL;
+	launch->params = NULL;
+}
+
+G_CONST_RETURN gchar *
+poppler_action_launch_get_file_name (PopplerActionLaunch *launch)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_LAUNCH (launch), NULL);
+
+	return launch->file_name;
+}
+
+G_CONST_RETURN gchar *
+poppler_action_launch_get_params (PopplerActionLaunch *launch)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_LAUNCH (launch), NULL);
+
+	return launch->params;
+}
+
+
+/* PopplerActionUri */
+typedef struct _PopplerActionUriClass PopplerActionUriClass;
+struct _PopplerActionUriClass
+{
+	PopplerActionClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerActionUri, poppler_action_uri, POPPLER_TYPE_ACTION);
+
+static void
+poppler_action_uri_finalize (GObject *object)
+{
+	PopplerActionUri *uri;
+	uri = POPPLER_ACTION_URI (object);
+
+	g_free (uri->uri);
+
+	G_OBJECT_CLASS (poppler_action_uri_parent_class)->finalize (object);
+}
+
+static void
+poppler_action_uri_get_property (GObject         *object,
+				    guint            prop_id,
+				    GValue          *value,
+				    GParamSpec      *pspec)
+{
+	PopplerActionUri *uri;
+	uri = POPPLER_ACTION_URI (object);
+
+	switch (prop_id) {
+	case PROP_URI:
+		g_value_set_string (value, uri->uri);
 		break;
 	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
-	}
-	    
-	return new_action;
+        }
 }
 
-PopplerDest *
+static void
+poppler_action_uri_set_property (GObject         *object,
+				    guint            prop_id,
+				    const GValue    *value,
+				    GParamSpec      *pspec)
+{
+	PopplerActionUri *uri;
+	uri = POPPLER_ACTION_URI (object);
+
+	switch (prop_id) {
+	case PROP_URI:
+		g_free (uri->uri);
+		uri->uri = g_strdup (g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+        }
+}
+
+
+static void
+poppler_action_uri_class_init (PopplerActionUriClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = poppler_action_uri_finalize;
+        gobject_class->get_property = poppler_action_uri_get_property;
+        gobject_class->set_property = poppler_action_uri_set_property;
+
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_URI,
+                 g_param_spec_string ("uri",
+				      "URI",
+				      "The URI of the action",
+				      NULL,
+				      ACTION_G_PARAM_FLAGS));
+}
+
+static void
+poppler_action_uri_init (PopplerActionUri *uri)
+{
+	uri->uri = NULL;
+}
+
+G_CONST_RETURN gchar*
+poppler_action_uri_get_uri (PopplerActionUri *uri)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_URI (uri), NULL);
+
+	return uri->uri;
+}
+
+
+/* PopplerActionNamed */
+typedef struct _PopplerActionNamedClass PopplerActionNamedClass;
+struct _PopplerActionNamedClass
+{
+	PopplerActionClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerActionNamed, poppler_action_named, POPPLER_TYPE_ACTION);
+
+static void
+poppler_action_named_finalize (GObject *object)
+{
+	PopplerActionNamed *named;
+	named = POPPLER_ACTION_NAMED (object);
+
+	g_free (named->named_dest);
+
+	G_OBJECT_CLASS (poppler_action_named_parent_class)->finalize (object);
+}
+
+static void
+poppler_action_named_get_property (GObject         *object,
+				   guint            prop_id,
+				   GValue          *value,
+				   GParamSpec      *pspec)
+{
+	PopplerActionNamed *named;
+	named = POPPLER_ACTION_NAMED (object);
+
+	switch (prop_id) {
+	case PROP_NAMED_DEST:
+		g_value_set_string (value, named->named_dest);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+        }
+}
+
+static void
+poppler_action_named_set_property (GObject         *object,
+				   guint            prop_id,
+				   const GValue    *value,
+				   GParamSpec      *pspec)
+{
+	PopplerActionNamed *named;
+	named = POPPLER_ACTION_NAMED (object);
+
+	switch (prop_id) {
+	case PROP_NAMED_DEST:
+		g_free (named->named_dest);
+		named->named_dest = g_strdup (g_value_get_string (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+        }
+}
+
+static void
+poppler_action_named_class_init (PopplerActionNamedClass *klass)
+{
+        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = poppler_action_named_finalize;
+        gobject_class->get_property = poppler_action_named_get_property;
+        gobject_class->set_property = poppler_action_named_set_property;
+
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_NAMED_DEST,
+                 g_param_spec_string ("named_dest",
+				      "Named Destination Name",
+				      "The named destination of the action",
+				      NULL,
+				      ACTION_G_PARAM_FLAGS));
+}
+
+static void
+poppler_action_named_init (PopplerActionNamed *named)
+{
+	named->named_dest = NULL;
+}
+
+G_CONST_RETURN gchar *
+poppler_action_named_get_named_dest (PopplerActionNamed *named)
+{
+	g_return_val_if_fail (POPPLER_IS_ACTION_NAMED (named), NULL);
+
+	return named->named_dest;
+}
+
+/* PopplerActionMovie */
+typedef struct _PopplerActionMovieClass PopplerActionMovieClass;
+struct _PopplerActionMovieClass
+{
+	PopplerActionClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerActionMovie, poppler_action_movie, POPPLER_TYPE_ACTION);
+
+static void
+poppler_action_movie_class_init (PopplerActionMovieClass *klass)
+{
+}
+
+static void
+poppler_action_movie_init (PopplerActionMovie *movie)
+{
+}
+
+
+static PopplerDest *
 dest_new_goto (PopplerDocument *document,
 	       LinkDest        *link_dest)
 {
@@ -274,99 +849,131 @@ dest_new_named (UGooString *named_dest)
 	return dest;
 }
 
-static void
+static PopplerAction*
 build_goto_dest (PopplerDocument *document,
-		 PopplerAction   *action,
+		 const gchar     *title,
 		 LinkGoTo        *link)
 {
-	LinkDest *link_dest;
-	UGooString *named_dest;
+	PopplerDest *dest = NULL;
+	PopplerAction *action;
 
-	/* Return if it isn't OK */
 	if (! link->isOk ()) {
-		action->goto_dest.dest = dest_new_goto (NULL, NULL);
-		return;
-	}
-	
-	link_dest = link->getDest ();
-	named_dest = link->getNamedDest ();
-
-	if (link_dest != NULL) {
-		action->goto_dest.dest = dest_new_goto (document, link_dest);
-	} else if (named_dest != NULL) {
-		action->goto_dest.dest = dest_new_named (named_dest);
+		dest = dest_new_goto (NULL, NULL);
 	} else {
-		action->goto_dest.dest = dest_new_goto (document, NULL);
+		LinkDest *link_dest;
+		UGooString *named_dest;
+
+		link_dest = link->getDest ();
+		named_dest = link->getNamedDest ();
+
+		if (link_dest != NULL) {
+			dest = dest_new_goto (document, link_dest);
+		} else if (named_dest != NULL) {
+			dest = dest_new_named (named_dest);
+		} else {
+			dest = dest_new_goto (document, NULL);
+		}
 	}
+
+	action = (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION_GOTO_DEST,
+						 "type", POPPLER_ACTION_GOTO_DEST,
+						 "title", title,
+						 "dest", dest,
+						 NULL);
+	poppler_dest_free (dest);
+	return action;
 }
 
-static void
-build_goto_remote (PopplerAction *action,
+static PopplerAction *
+build_goto_remote (const gchar   *title,
 		   LinkGoToR     *link)
 {
-	LinkDest *link_dest;
-	UGooString *named_dest;
-	
-	/* Return if it isn't OK */
+	PopplerDest *dest;
+	PopplerAction *action;
+	gchar *file_name = NULL;
+
 	if (! link->isOk ()) {
-		action->goto_remote.dest = dest_new_goto (NULL, NULL);
-		return;
-	}
+		dest = dest_new_goto (NULL, NULL);
+	} else {
+		LinkDest *link_dest = link->getDest ();
+		UGooString *named_dest = link->getNamedDest ();
 
-	if (link->getFileName()->getCString ())
-		action->goto_remote.file_name = g_strdup (link->getFileName()->getCString ());
+		file_name = link->getFileName()->getCString ();
 
-	link_dest = link->getDest ();
-	named_dest = link->getNamedDest ();
-	
-	if (link_dest != NULL) {
-		action->goto_remote.dest = dest_new_goto (NULL, link_dest);
-	} else if (named_dest != NULL) {
-		action->goto_remote.dest = dest_new_named (named_dest);
-	} else {
-		action->goto_remote.dest = dest_new_goto (NULL, NULL);
+		if (link_dest != NULL) {
+			dest = dest_new_goto (NULL, link_dest);
+		} else if (named_dest != NULL) {
+			dest = dest_new_named (named_dest);
+		} else {
+			dest = dest_new_goto (NULL, NULL);
+		}
 	}
+
+	action = (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION_GOTO_REMOTE,
+						 "type", POPPLER_ACTION_GOTO_REMOTE,
+						 "title", title,
+						 "file_name", file_name,
+						 "dest", dest,
+						 NULL);
+	poppler_dest_free (dest);
+	return action;
 }
 
-static void
-build_launch (PopplerAction *action,
+static PopplerAction *
+build_launch (const gchar   *title,
 	      LinkLaunch    *link)
 {
+	gchar *file_name = NULL;
+	gchar *params = NULL;
+
 	if (link->getFileName()) {
-		action->launch.file_name = g_strdup (link->getFileName()->getCString ());
+		file_name = link->getFileName()->getCString ();
 	}
 	if (link->getParams()) {
-		action->launch.params = g_strdup (link->getParams()->getCString ());
+		params = link->getParams()->getCString ();
 	}
+
+	return (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION_LAUNCH,
+					       "type", POPPLER_ACTION_LAUNCH,
+					       "title", title,
+					       "file_name", file_name,
+					       "params", params,
+					       NULL);
 }
 
-static void
-build_uri (PopplerAction *action,
+static PopplerAction *
+build_uri (const gchar   *title,
 	   LinkURI       *link)
 {
-	gchar *uri;
-
-	uri = link->getURI()->getCString ();
-	if (uri != NULL)
-		action->uri.uri = g_strdup (uri);
+	gchar *uri = link->getURI()->getCString ();
+	return (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION_URI,
+					       "type", POPPLER_ACTION_URI,
+					       "title", title,
+					       "uri", uri,
+					       NULL);
 }
 
-static void
-build_named (PopplerAction *action,
+static PopplerAction *
+build_named (const gchar   *title,
 	     LinkNamed     *link)
 {
-	gchar *name;
-
-	name = link->getName ()->getCString ();
-	if (name != NULL)
-		action->named.named_dest = g_strdup (name);
+	gchar *named_dest = link->getName ()->getCString ();
+	return (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION_NAMED,
+					       "type", POPPLER_ACTION_NAMED,
+					       "title", title,
+					       "named_dest", named_dest,
+					       NULL);
 }
 
-static void
-build_movie (PopplerAction *action,
+static PopplerAction *
+build_movie (const gchar   *title,
 	     LinkAction    *link)
 {
 	/* FIXME: Write */
+	return (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION_MOVIE,
+					       "type", POPPLER_ACTION_MOVIE,
+					       "title", title,
+					       NULL);
 }
 
 PopplerAction *
@@ -376,44 +983,41 @@ _poppler_action_new (PopplerDocument *do
 {
 	PopplerAction *action;
 
-	action = g_new0 (PopplerAction, 1);
-
-	if (title)
-		action->any.title = g_strdup (title);
-
 	if (link == NULL) {
-		action->type = POPPLER_ACTION_UNKNOWN;
-		return action;
+		return (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION,
+						       "type", POPPLER_ACTION_UNKNOWN,
+						       "title", title,
+						       NULL);
 	}
 
 	switch (link->getKind ()) {
 	case actionGoTo:
-		action->type = POPPLER_ACTION_GOTO_DEST;
-		build_goto_dest (document, action, dynamic_cast <LinkGoTo *> (link));
+		action = build_goto_dest (document, title,
+					  dynamic_cast <LinkGoTo *> (link));
 		break;
 	case actionGoToR:
-		action->type = POPPLER_ACTION_GOTO_REMOTE;
-		build_goto_remote (action, dynamic_cast <LinkGoToR *> (link));
+		action = build_goto_remote (title,
+					    dynamic_cast <LinkGoToR *> (link));
 		break;
 	case actionLaunch:
-		action->type = POPPLER_ACTION_LAUNCH;
-		build_launch (action, dynamic_cast <LinkLaunch *> (link));
+		action = build_launch (title,
+				       dynamic_cast <LinkLaunch *> (link));
 		break;
 	case actionURI:
-		action->type = POPPLER_ACTION_URI;
-		build_uri (action, dynamic_cast <LinkURI *> (link));
+		action = build_uri (title, dynamic_cast <LinkURI *> (link));
 		break;
 	case actionNamed:
-		action->type = POPPLER_ACTION_NAMED;
-		build_named (action, dynamic_cast <LinkNamed *> (link));
+		action = build_named (title, dynamic_cast <LinkNamed *> (link));
 		break;
 	case actionMovie:
-		action->type = POPPLER_ACTION_MOVIE;
-		build_movie (action, link);
+		action = build_movie (title, link);
 		break;
 	case actionUnknown:
 	default:
-		action->type = POPPLER_ACTION_UNKNOWN;
+		action = (PopplerAction *) g_object_new (POPPLER_TYPE_ACTION,
+							 "type", POPPLER_ACTION_UNKNOWN,
+							 "title", title,
+							 NULL);
 		break;
 	}
 
Index: glib/poppler-action.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-action.h,v
retrieving revision 1.6
diff -u -p -r1.6 poppler-action.h
--- glib/poppler-action.h	19 May 2006 22:26:03 -0000	1.6
+++ glib/poppler-action.h	21 May 2006 13:16:19 -0000
@@ -25,6 +25,37 @@
 
 G_BEGIN_DECLS
 
+#define POPPLER_TYPE_ACTION             (poppler_action_get_type ())
+#define POPPLER_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION, PopplerAction))
+#define POPPLER_IS_ACTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION))
+
+#define POPPLER_TYPE_ACTION_GOTO_DEST    (poppler_action_goto_dest_get_type ())
+#define POPPLER_ACTION_GOTO_DEST(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION_GOTO_DEST, PopplerActionGotoDest))
+#define POPPLER_IS_ACTION_GOTO_DEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION_GOTO_DEST))
+
+#define POPPLER_TYPE_ACTION_GOTO_REMOTE             (poppler_action_goto_remote_get_type ())
+#define POPPLER_ACTION_GOTO_REMOTE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION_GOTO_REMOTE, PopplerActionGotoRemote))
+#define POPPLER_IS_ACTION_GOTO_REMOTE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION_GOTO_REMOTE))
+
+#define POPPLER_TYPE_ACTION_LAUNCH             (poppler_action_launch_get_type ())
+#define POPPLER_ACTION_LAUNCH(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION_LAUNCH, PopplerActionLaunch))
+#define POPPLER_IS_ACTION_LAUNCH(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION_LAUNCH))
+
+#define POPPLER_TYPE_ACTION_URI             (poppler_action_uri_get_type ())
+#define POPPLER_ACTION_URI(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION_URI, PopplerActionUri))
+#define POPPLER_IS_ACTION_URI(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION_URI))
+
+#define POPPLER_TYPE_ACTION_NAMED             (poppler_action_named_get_type ())
+#define POPPLER_ACTION_NAMED(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION_NAMED, PopplerActionNamed))
+#define POPPLER_IS_ACTION_NAMED(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION_NAMED))
+
+#define POPPLER_TYPE_ACTION_MOVIE             (poppler_action_movie_get_type ())
+#define POPPLER_ACTION_MOVIE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION_MOVIE, PopplerActionMovie))
+#define POPPLER_IS_ACTION_MOVIE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ACTION_MOVIE))
+
+#define POPPLER_TYPE_DEST              (poppler_dest_get_type ())
+
+
 typedef enum
 {
 	POPPLER_ACTION_UNKNOWN,		/* unknown action */
@@ -51,7 +82,6 @@ typedef enum
 } PopplerDestType;
 
 /* Define the PopplerAction types */
-typedef struct _PopplerActionAny        PopplerActionAny;
 typedef struct _PopplerActionGotoDest   PopplerActionGotoDest;
 typedef struct _PopplerActionGotoRemote PopplerActionGotoRemote;
 typedef struct _PopplerActionLaunch     PopplerActionLaunch;
@@ -76,79 +106,43 @@ struct _PopplerDest
 };
 
 
-struct _PopplerActionAny
-{
-	PopplerActionType type;
-	gchar *title;
-};
+GType          poppler_action_get_type (void) G_GNUC_CONST;
 
-struct _PopplerActionGotoDest
-{
-	PopplerActionType type;
-	gchar *title;
+PopplerActionType     poppler_action_get_action_type (PopplerAction *action);
+G_CONST_RETURN gchar *poppler_action_get_title       (PopplerAction *action);
 
-	PopplerDest *dest;
-};
 
-struct _PopplerActionGotoRemote
-{
-	PopplerActionType type;
-	gchar *title;
+GType          poppler_action_goto_dest_get_type (void) G_GNUC_CONST;
 
-	gchar *file_name;
-	PopplerDest *dest;
-};
+G_CONST_RETURN PopplerDest *poppler_action_goto_dest_get_dest (PopplerActionGotoDest *goto_dest);
 
-struct _PopplerActionLaunch
-{
-	PopplerActionType type;
-	gchar *title;
 
-	gchar *file_name;
-	gchar *params;
-};
+GType          poppler_action_goto_remote_get_type (void) G_GNUC_CONST;
 
-struct _PopplerActionUri
-{
-	PopplerActionType type;
-	gchar *title;
+G_CONST_RETURN gchar       *poppler_action_goto_remote_get_file_name (PopplerActionGotoRemote *goto_remote);
+G_CONST_RETURN PopplerDest *poppler_action_goto_remote_get_dest      (PopplerActionGotoRemote *goto_remote);
 
-	char *uri;
-};
 
-struct _PopplerActionNamed
-{
-	PopplerActionType type;
-	gchar *title;
+GType          poppler_action_launch_get_type (void) G_GNUC_CONST;
 
-	gchar *named_dest;
-};
+G_CONST_RETURN gchar *poppler_action_launch_get_file_name (PopplerActionLaunch *launch);
+G_CONST_RETURN gchar *poppler_action_launch_get_params    (PopplerActionLaunch *launch);
 
-struct _PopplerActionMovie
-{
-	PopplerActionType type;
-	gchar *title;
-};
 
-union _PopplerAction
-{
-	PopplerActionType type;
-	PopplerActionAny any;
-	PopplerActionGotoDest goto_dest;
-	PopplerActionGotoRemote goto_remote;
-	PopplerActionLaunch launch;
-	PopplerActionUri uri;
-	PopplerActionNamed named;
-	PopplerActionMovie movie;
-};
+GType          poppler_action_uri_get_type (void) G_GNUC_CONST;
 
-#define POPPLER_TYPE_ACTION             (poppler_action_get_type ())
-#define POPPLER_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION, PopplerAction))
+G_CONST_RETURN gchar *poppler_action_uri_get_uri (PopplerActionUri *uri);
 
-GType          poppler_action_get_type (void) G_GNUC_CONST;
 
-void           poppler_action_free     (PopplerAction *action);
-PopplerAction *poppler_action_copy     (PopplerAction *action);
+GType          poppler_action_named_get_type (void) G_GNUC_CONST;
+
+G_CONST_RETURN gchar *poppler_action_named_get_named_dest (PopplerActionNamed *named);
+
+
+GType          poppler_action_movie_get_type (void) G_GNUC_CONST;
+
+
+GType          poppler_dest_get_type   (void) G_GNUC_CONST;
 
 
 #define POPPLER_TYPE_DEST              (poppler_dest_get_type ())
Index: glib/poppler-page.cc
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-page.cc,v
retrieving revision 1.50
diff -u -p -r1.50 poppler-page.cc
--- glib/poppler-page.cc	19 May 2006 21:42:54 -0000	1.50
+++ glib/poppler-page.cc	21 May 2006 13:16:20 -0000
@@ -880,7 +880,7 @@ poppler_page_get_link_mapping (PopplerPa
 static void
 poppler_mapping_free (PopplerLinkMapping *mapping)
 {
-	poppler_action_free (mapping->action);
+	g_object_unref (mapping->action);
 	g_free (mapping);
 }
 
@@ -972,7 +972,8 @@ poppler_link_mapping_copy (PopplerLinkMa
 	
 	*new_mapping = *mapping;
 	if (new_mapping->action)
-		new_mapping->action = poppler_action_copy (new_mapping->action);
+		new_mapping->action =
+                        POPPLER_ACTION (g_object_ref (new_mapping->action));
 
 	return new_mapping;
 }
@@ -981,7 +982,7 @@ void
 poppler_link_mapping_free (PopplerLinkMapping *mapping)
 {
 	if (mapping)
-		poppler_action_free (mapping->action);
+		g_object_unref (mapping->action);
 
 	g_free (mapping);
 }
Index: glib/poppler-private.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-private.h,v
retrieving revision 1.16
diff -u -p -r1.16 poppler-private.h
--- glib/poppler-private.h	19 May 2006 20:54:13 -0000	1.16
+++ glib/poppler-private.h	21 May 2006 13:16:20 -0000
@@ -60,6 +60,57 @@ struct _PopplerPage
   Gfx *gfx;
 };
 
+
+struct _PopplerAction
+{
+    GObject parent_instance;
+
+    PopplerActionType type;
+    gchar *title;
+};
+
+struct _PopplerActionGotoDest
+{
+    PopplerAction parent_instance;
+
+    PopplerDest *dest;
+};
+
+struct _PopplerActionGotoRemote
+{
+    PopplerAction parent_instance;
+
+    gchar *file_name;
+    PopplerDest *dest;
+};
+
+struct _PopplerActionLaunch
+{
+    PopplerAction parent_instance;
+
+    gchar *file_name;
+    gchar *params;
+};
+
+struct _PopplerActionUri
+{
+    PopplerAction parent_instance;
+
+    char *uri;
+};
+
+struct _PopplerActionNamed
+{
+    PopplerAction parent_instance;
+
+    gchar *named_dest;
+};
+
+struct _PopplerActionMovie
+{
+    PopplerAction parent_instance;
+};
+
 PopplerPage   *_poppler_page_new   (PopplerDocument *document,
 				    Page            *page,
 				    int              index);
Index: glib/poppler.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler.h,v
retrieving revision 1.12
diff -u -p -r1.12 poppler.h
--- glib/poppler.h	16 Apr 2006 22:59:44 -0000	1.12
+++ glib/poppler.h	21 May 2006 13:16:20 -0000
@@ -50,7 +50,7 @@ typedef struct _PopplerLinkMapping Poppl
 typedef struct _PopplerPage        PopplerPage;
 typedef struct _PopplerFontInfo    PopplerFontInfo;
 typedef struct _PopplerPSFile      PopplerPSFile;
-typedef union  _PopplerAction      PopplerAction;
+typedef struct _PopplerAction      PopplerAction;
 typedef struct _PopplerDest        PopplerDest;
 
 
Index: glib/test-poppler-glib.c
===================================================================
RCS file: /cvs/poppler/poppler/glib/test-poppler-glib.c,v
retrieving revision 1.18
diff -u -p -r1.18 test-poppler-glib.c
--- glib/test-poppler-glib.c	28 Feb 2006 18:25:00 -0000	1.18
+++ glib/test-poppler-glib.c	21 May 2006 13:16:20 -0000
@@ -16,8 +16,8 @@ print_index (PopplerIndexIter *iter)
       PopplerIndexIter *child;
 
       action = poppler_index_iter_get_action (iter);
-      g_print ("Action: %d\n", action->type);
-      poppler_action_free (action);
+      g_print ("Action: %d\n", poppler_action_get_action_type(action));
+      g_object_unref (action);
       child = poppler_index_iter_get_child (iter);
       if (child)
 	print_index (child);