blob: 0f1f38c530dd602532deed8091d93a3a61179245 [file] [log] [blame]
/* poppler-action.cc: glib wrapper for poppler -*- c-basic-offset: 8 -*-
* Copyright (C) 2005, Red Hat, Inc.
*
* This program 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 2, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "poppler.h"
#include "poppler-private.h"
static PopplerDest *
poppler_dest_copy (PopplerDest *dest)
{
PopplerDest *new_dest;
new_dest = g_new0 (PopplerDest, 1);
memcpy (new_dest, dest, sizeof (PopplerDest));
return new_dest;
}
static void
poppler_dest_free (PopplerDest *dest)
{
g_free (dest);
}
GType
poppler_action_get_type (void)
{
static GType our_type = 0;
if (our_type == 0)
our_type = g_boxed_type_register_static ("PopplerAction",
(GBoxedCopyFunc) poppler_action_copy,
(GBoxedFreeFunc) poppler_action_free);
return our_type;
}
void
poppler_action_free (PopplerAction *action)
{
if (action == NULL)
return;
/* Action specific stuff */
if (action->type == POPPLER_ACTION_GOTO_DEST) {
poppler_dest_free (action->goto_dest.dest);
} else if (action->type == POPPLER_ACTION_GOTO_REMOTE) {
poppler_dest_free (action->goto_remote.dest);
g_free (action->goto_remote.file_name);
} else if (action->type == POPPLER_ACTION_URI) {
g_free (action->uri.uri);
}
g_free (action->any.title);
g_free (action);
}
PopplerAction *
poppler_action_copy (PopplerAction *action)
{
PopplerAction *new_action;
g_return_val_if_fail (action != NULL, NULL);
/* Do a straight copy of the memory */
new_action = g_new0 (PopplerAction, 1);
memcpy (new_action, action, sizeof (PopplerAction));
if (action->any.title != NULL)
new_action->any.title = g_strdup (action->any.title);
if (action->type == POPPLER_ACTION_GOTO_DEST) {
new_action->goto_dest.dest = poppler_dest_copy (action->goto_dest.dest);
} else if (action->type == POPPLER_ACTION_GOTO_REMOTE) {
new_action->goto_remote.dest = poppler_dest_copy (action->goto_remote.dest);
}
return new_action;
}
static PopplerDest *
build_dest (PopplerDocument *document,
LinkDest *link_dest)
{
PopplerDest *dest;
dest = g_new0 (PopplerDest, 1);
if (link_dest == NULL) {
dest->type = POPPLER_DEST_UNKNOWN;
return dest;
}
switch (link_dest->getKind ()) {
case destXYZ:
dest->type = POPPLER_DEST_XYZ;
break;
case destFit:
dest->type = POPPLER_DEST_FIT;
break;
case destFitH:
dest->type = POPPLER_DEST_FITH;
break;
case destFitV:
dest->type = POPPLER_DEST_FITV;
break;
case destFitR:
dest->type = POPPLER_DEST_FITR;
break;
case destFitB:
dest->type = POPPLER_DEST_FITB;
break;
case destFitBH:
dest->type = POPPLER_DEST_FITBH;
break;
case destFitBV:
dest->type = POPPLER_DEST_FITBV;
break;
default:
dest->type = POPPLER_DEST_UNKNOWN;
}
if (link_dest->isPageRef ()) {
if (document) {
Ref page_ref = link_dest->getPageRef ();
dest->page_num = document->doc->findPage (page_ref.num, page_ref.gen);
} else {
/* FIXME: We don't keep areound the page_ref for the
* remote doc, so we can't look this up. Guess that
* it's 0*/
dest->page_num = 0;
}
} else {
dest->page_num = link_dest->getPageNum ();
}
dest->left = link_dest->getLeft ();
dest->bottom = link_dest->getBottom ();
dest->right = link_dest->getRight ();
dest->top = link_dest->getTop ();
dest->zoom = link_dest->getZoom ();
dest->change_left = link_dest->getChangeLeft ();
dest->change_top = link_dest->getChangeTop ();
dest->change_zoom = link_dest->getChangeZoom ();
return dest;
}
static void
build_goto_dest (PopplerDocument *document,
PopplerAction *action,
LinkGoTo *link)
{
LinkDest *link_dest;
GooString *named_dest;
/* Return if it isn't OK */
if (! link->isOk ()) {
action->goto_dest.dest = build_dest (NULL, NULL);
return;
}
link_dest = link->getDest ();
named_dest = link->getNamedDest ();
if (link_dest != NULL) {
action->goto_dest.dest = build_dest (document, link_dest);
} else if (named_dest != NULL) {
link_dest = document->doc->findDest (named_dest);
action->goto_dest.dest = build_dest (document, link_dest);
delete link_dest;
} else {
action->goto_dest.dest = build_dest (document, NULL);
}
}
static void
build_goto_remote (PopplerAction *action,
LinkGoToR *link)
{
/* Return if it isn't OK */
if (! link->isOk ()) {
action->goto_remote.dest = build_dest (NULL, NULL);
return;
}
if (link->getFileName()->getCString ())
action->goto_remote.file_name = g_strdup (link->getFileName()->getCString ());
/* FIXME, we don't handle named dest yet. */
action->goto_dest.dest = build_dest (NULL, link->getDest ());
}
static void
build_launch (PopplerAction *action,
LinkAction *link)
{
/* FIXME: Write */
}
static void
build_uri (PopplerAction *action,
LinkURI *link)
{
gchar *uri;
uri = link->getURI()->getCString ();
if (uri != NULL)
action->uri.uri = g_strdup (uri);
}
static void
build_named (PopplerAction *action,
LinkAction *link)
{
/* FIXME: Write */
}
static void
build_movie (PopplerAction *action,
LinkAction *link)
{
/* FIXME: Write */
}
PopplerAction *
_poppler_action_new (PopplerDocument *document,
LinkAction *link,
const gchar *title)
{
PopplerAction *action;
action = g_new0 (PopplerAction, 1);
if (link == NULL) {
action->type = POPPLER_ACTION_UNKNOWN;
return action;
}
switch (link->getKind ()) {
case actionGoTo:
action->type = POPPLER_ACTION_GOTO_DEST;
build_goto_dest (document, action, dynamic_cast <LinkGoTo *> (link));
break;
case actionGoToR:
action->type = POPPLER_ACTION_GOTO_REMOTE;
build_goto_remote (action, dynamic_cast <LinkGoToR *> (link));
break;
case actionLaunch:
action->type = POPPLER_ACTION_LAUNCH;
build_launch (action, link);
break;
case actionURI:
action->type = POPPLER_ACTION_URI;
build_uri (action, dynamic_cast <LinkURI *> (link));
break;
case actionNamed:
action->type = POPPLER_ACTION_NAMED;
build_named (action, link);
break;
case actionMovie:
action->type = POPPLER_ACTION_MOVIE;
build_movie (action, link);
break;
case actionUnknown:
default:
action->type = POPPLER_ACTION_UNKNOWN;
break;
}
if (title)
action->any.title = g_strdup (title);
return action;
}