diff options
Diffstat (limited to 'properties')
-rw-r--r-- | properties/Makefile.am | 35 | ||||
-rw-r--r-- | properties/ev-properties-main.c | 159 | ||||
-rw-r--r-- | properties/ev-properties-view.c | 399 | ||||
-rw-r--r-- | properties/ev-properties-view.h | 50 |
4 files changed, 643 insertions, 0 deletions
diff --git a/properties/Makefile.am b/properties/Makefile.am new file mode 100644 index 00000000..3ef1b82c --- /dev/null +++ b/properties/Makefile.am @@ -0,0 +1,35 @@ +INCLUDES= \ + -DEVINCEDATADIR=\"$(pkgdatadir)\" \ + -DMATELOCALEDIR=\"$(datadir)/locale\" \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(FRONTEND_CFLAGS) \ + $(CAJA_CFLAGS) \ + $(DISABLE_DEPRECATED) \ + $(WARN_CFLAGS) + +noinst_LTLIBRARIES = libevproperties.la + +libevproperties_la_SOURCES= \ + ev-properties-view.c \ + ev-properties-view.h + +if ENABLE_CAJA + +cajaextension_LTLIBRARIES = libevince-properties-page.la + +libevince_properties_page_la_CFLAGS = -I$(top_srcdir) +libevince_properties_page_la_SOURCES = \ + ev-properties-main.c + +libevince_properties_page_la_LIBADD = \ + libevproperties.la \ + $(top_builddir)/libdocument/libevdocument.la \ + $(FRONTEND_LIBS) \ + $(CAJA_LIBS) + +libevince_properties_page_la_LDFLAGS = -module -avoid-version -no-undefined + +endif # ENABLE_CAJA + +-include $(top_srcdir)/git.mk diff --git a/properties/ev-properties-main.c b/properties/ev-properties-main.c new file mode 100644 index 00000000..b78396c3 --- /dev/null +++ b/properties/ev-properties-main.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2000, 2001 Eazel Inc. + * Copyright (C) 2003 Andrew Sobala <[email protected]> + * Copyright (C) 2005 Bastien Nocera <[email protected]> + * + * This library 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 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Ev project hereby grant permission for non-gpl compatible GStreamer + * plugins to be used and distributed together with GStreamer and Ev. This + * permission are above and beyond the permissions granted by the GPL license + * Ev is covered by. + * + * Monday 7th February 2005: Christian Schaller: Add excemption clause. + * See license_change file for details. + * + */ + +#include <config.h> + +#include <string.h> + +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> + +#include <libcaja-extension/caja-extension-types.h> +#include <libcaja-extension/caja-property-page-provider.h> + +#include <evince-document.h> +#include "ev-properties-view.h" + +static GType epp_type = 0; +static void property_page_provider_iface_init + (CajaPropertyPageProviderIface *iface); +static GList *ev_properties_get_pages + (CajaPropertyPageProvider *provider, GList *files); + +static void +ev_properties_plugin_register_type (GTypeModule *module) +{ + const GTypeInfo info = { + sizeof (GObjectClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) NULL, + NULL, + NULL, + sizeof (GObject), + 0, + (GInstanceInitFunc) NULL + }; + const GInterfaceInfo property_page_provider_iface_info = { + (GInterfaceInitFunc)property_page_provider_iface_init, + NULL, + NULL + }; + + epp_type = g_type_module_register_type (module, G_TYPE_OBJECT, + "EvPropertiesPlugin", + &info, 0); + g_type_module_add_interface (module, + epp_type, + CAJA_TYPE_PROPERTY_PAGE_PROVIDER, + &property_page_provider_iface_info); +} + +static void +property_page_provider_iface_init (CajaPropertyPageProviderIface *iface) +{ + iface->get_pages = ev_properties_get_pages; +} + +static GList * +ev_properties_get_pages (CajaPropertyPageProvider *provider, + GList *files) +{ + GError *error = NULL; + EvDocument *document; + GList *pages = NULL; + CajaFileInfo *file; + gchar *uri = NULL; + gchar *mime_type = NULL; + GtkWidget *page, *label; + CajaPropertyPage *property_page; + + /* only add properties page if a single file is selected */ + if (files == NULL || files->next != NULL) + goto end; + file = files->data; + + /* okay, make the page */ + uri = caja_file_info_get_uri (file); + mime_type = caja_file_info_get_mime_type (file); + + document = ev_backends_manager_get_document (mime_type); + if (!document) + goto end; + + ev_document_load (document, uri, &error); + if (error) { + g_error_free (error); + goto end; + } + + label = gtk_label_new (_("Document")); + page = ev_properties_view_new (uri); + ev_properties_view_set_info (EV_PROPERTIES_VIEW (page), + ev_document_get_info (document)); + gtk_widget_show (page); + property_page = caja_property_page_new ("document-properties", + label, page); + g_object_unref (document); + + pages = g_list_prepend (pages, property_page); + +end: + g_free (uri); + g_free (mime_type); + + return pages; +} + +/* --- extension interface --- */ +void +caja_module_initialize (GTypeModule *module) +{ + ev_properties_plugin_register_type (module); + ev_properties_view_register_type (module); + + ev_init (); +} + +void +caja_module_shutdown (void) +{ + ev_shutdown (); +} + +void +caja_module_list_types (const GType **types, + int *num_types) +{ + static GType type_list[1]; + + type_list[0] = epp_type; + *types = type_list; + *num_types = G_N_ELEMENTS (type_list); +} diff --git a/properties/ev-properties-view.c b/properties/ev-properties-view.c new file mode 100644 index 00000000..38a75641 --- /dev/null +++ b/properties/ev-properties-view.c @@ -0,0 +1,399 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* this file is part of evince, a mate document viewer + * + * Copyright (C) 2005 Red Hat, Inc + * + * Evince 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 of the License, or + * (at your option) any later version. + * + * Evince 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include <string.h> +#include <sys/time.h> +#include <time.h> + +#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT +#include <langinfo.h> +#endif + +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> + +#include "ev-properties-view.h" + +typedef enum { + TITLE_PROPERTY, + URI_PROPERTY, + SUBJECT_PROPERTY, + AUTHOR_PROPERTY, + KEYWORDS_PROPERTY, + PRODUCER_PROPERTY, + CREATOR_PROPERTY, + CREATION_DATE_PROPERTY, + MOD_DATE_PROPERTY, + N_PAGES_PROPERTY, + LINEARIZED_PROPERTY, + FORMAT_PROPERTY, + SECURITY_PROPERTY, + PAPER_SIZE_PROPERTY, + N_PROPERTIES +} Property; + +typedef struct { + Property property; + const char *label; +} PropertyInfo; + +static const PropertyInfo properties_info[] = { + { TITLE_PROPERTY, N_("Title:") }, + { URI_PROPERTY, N_("Location:") }, + { SUBJECT_PROPERTY, N_("Subject:") }, + { AUTHOR_PROPERTY, N_("Author:") }, + { KEYWORDS_PROPERTY, N_("Keywords:") }, + { PRODUCER_PROPERTY, N_("Producer:") }, + { CREATOR_PROPERTY, N_("Creator:") }, + { CREATION_DATE_PROPERTY, N_("Created:") }, + { MOD_DATE_PROPERTY, N_("Modified:") }, + { N_PAGES_PROPERTY, N_("Number of Pages:") }, + { LINEARIZED_PROPERTY, N_("Optimized:") }, + { FORMAT_PROPERTY, N_("Format:") }, + { SECURITY_PROPERTY, N_("Security:") }, + { PAPER_SIZE_PROPERTY, N_("Paper Size:") } +}; + +struct _EvPropertiesView { + GtkVBox base_instance; + + GtkWidget *table; + GtkWidget *labels[N_PROPERTIES]; + gchar *uri; +}; + +struct _EvPropertiesViewClass { + GtkVBoxClass base_class; +}; + +G_DEFINE_TYPE (EvPropertiesView, ev_properties_view, GTK_TYPE_VBOX) + +static void +ev_properties_view_dispose (GObject *object) +{ + EvPropertiesView *properties = EV_PROPERTIES_VIEW (object); + + if (properties->uri) { + g_free (properties->uri); + properties->uri = NULL; + } + + G_OBJECT_CLASS (ev_properties_view_parent_class)->dispose (object); +} + +static void +ev_properties_view_class_init (EvPropertiesViewClass *properties_class) +{ + GObjectClass *g_object_class = G_OBJECT_CLASS (properties_class); + + g_object_class->dispose = ev_properties_view_dispose; +} + +/* This is cut out of gconvert.c from glib (and mildly modified). Not all + backends give valid UTF-8 for properties, so we make sure that is. + */ +static gchar * +make_valid_utf8 (const gchar *name) +{ + GString *string; + const gchar *remainder, *invalid; + gint remaining_bytes, valid_bytes; + + string = NULL; + remainder = name; + remaining_bytes = strlen (name); + + while (remaining_bytes != 0) + { + if (g_utf8_validate (remainder, remaining_bytes, &invalid)) + break; + valid_bytes = invalid - remainder; + + if (string == NULL) + string = g_string_sized_new (remaining_bytes); + + g_string_append_len (string, remainder, valid_bytes); + g_string_append_c (string, '?'); + + remaining_bytes -= valid_bytes + 1; + remainder = invalid + 1; + } + + if (string == NULL) + return g_strdup (name); + + g_string_append (string, remainder); + + g_assert (g_utf8_validate (string->str, -1, NULL)); + + return g_string_free (string, FALSE); +} + +static void +set_property (EvPropertiesView *properties, + GtkTable *table, + Property property, + const gchar *text, + gint *row) +{ + GtkWidget *label; + gchar *markup; + gchar *valid_text; + + if (!properties->labels[property]) { + label = gtk_label_new (NULL); + g_object_set (G_OBJECT (label), "xalign", 0.0, NULL); + markup = g_strdup_printf ("<b>%s</b>", _(properties_info[property].label)); + gtk_label_set_markup (GTK_LABEL (label), markup); + g_free (markup); + + gtk_table_attach (table, label, 0, 1, *row, *row + 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (label); + } + + if (!properties->labels[property]) { + label = gtk_label_new (NULL); + + g_object_set (G_OBJECT (label), + "xalign", 0.0, + "width_chars", 25, + "selectable", TRUE, + "ellipsize", PANGO_ELLIPSIZE_END, + NULL); + } else { + label = properties->labels[property]; + } + + if (text == NULL || text[0] == '\000') { + markup = g_markup_printf_escaped ("<i>%s</i>", _("None")); + gtk_label_set_markup (GTK_LABEL (label), markup); + g_free (markup); + } else { + valid_text = make_valid_utf8 (text ? text : ""); + gtk_label_set_text (GTK_LABEL (label), valid_text); + g_free (valid_text); + } + + if (!properties->labels[property]) { + gtk_table_attach (table, label, 1, 2, *row, *row + 1, + GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0); + properties->labels[property] = label; + } + + gtk_widget_show (label); + + *row += 1; +} + +static GtkUnit +get_default_user_units (void) +{ + /* Translate to the default units to use for presenting + * lengths to the user. Translate to default:inch if you + * want inches, otherwise translate to default:mm. + * Do *not* translate it to "predefinito:mm", if it + * it isn't default:mm or default:inch it will not work + */ + gchar *e = _("default:mm"); + +#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT + gchar *imperial = NULL; + + imperial = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT); + if (imperial && imperial[0] == 2) + return GTK_UNIT_INCH; /* imperial */ + if (imperial && imperial[0] == 1) + return GTK_UNIT_MM; /* metric */ +#endif + + if (strcmp (e, "default:mm") == 0) + return GTK_UNIT_MM; + if (strcmp (e, "default:inch") == 0) + return GTK_UNIT_INCH; + + g_warning ("Whoever translated default:mm did so wrongly.\n"); + + return GTK_UNIT_MM; +} + +static gdouble +get_tolerance (gdouble size) +{ + if (size < 150.0f) + return 1.5f; + else if (size >= 150.0f && size <= 600.0f) + return 2.0f; + else + return 3.0f; +} + +static char * +ev_regular_paper_size (const EvDocumentInfo *info) +{ + GList *paper_sizes, *l; + gchar *exact_size; + gchar *str = NULL; + GtkUnit units; + + units = get_default_user_units (); + + if (units == GTK_UNIT_MM) { + exact_size = g_strdup_printf(_("%.0f × %.0f mm"), + info->paper_width, + info->paper_height); + } else { + exact_size = g_strdup_printf (_("%.2f × %.2f inch"), + info->paper_width / 25.4f, + info->paper_height / 25.4f); + } + + paper_sizes = gtk_paper_size_get_paper_sizes (FALSE); + + for (l = paper_sizes; l && l->data; l = g_list_next (l)) { + GtkPaperSize *size = (GtkPaperSize *) l->data; + gdouble paper_width; + gdouble paper_height; + gdouble width_tolerance; + gdouble height_tolerance; + + paper_width = gtk_paper_size_get_width (size, GTK_UNIT_MM); + paper_height = gtk_paper_size_get_height (size, GTK_UNIT_MM); + + width_tolerance = get_tolerance (paper_width); + height_tolerance = get_tolerance (paper_height); + + if (ABS (info->paper_height - paper_height) <= height_tolerance && + ABS (info->paper_width - paper_width) <= width_tolerance) { + /* Note to translators: first placeholder is the paper name (eg. + * A4), second placeholder is the paper size (eg. 297x210 mm) */ + str = g_strdup_printf (_("%s, Portrait (%s)"), + gtk_paper_size_get_display_name (size), + exact_size); + } else if (ABS (info->paper_width - paper_height) <= height_tolerance && + ABS (info->paper_height - paper_width) <= width_tolerance) { + /* Note to translators: first placeholder is the paper name (eg. + * A4), second placeholder is the paper size (eg. 297x210 mm) */ + str = g_strdup_printf ( _("%s, Landscape (%s)"), + gtk_paper_size_get_display_name (size), + exact_size); + } + } + + g_list_foreach (paper_sizes, (GFunc) gtk_paper_size_free, NULL); + g_list_free (paper_sizes); + + if (str != NULL) { + g_free (exact_size); + return str; + } + + return exact_size; +} + +void +ev_properties_view_set_info (EvPropertiesView *properties, const EvDocumentInfo *info) +{ + GtkWidget *table; + gchar *text; + gint row = 0; + + table = properties->table; + + if (info->fields_mask & EV_DOCUMENT_INFO_TITLE) { + set_property (properties, GTK_TABLE (table), TITLE_PROPERTY, info->title, &row); + } + set_property (properties, GTK_TABLE (table), URI_PROPERTY, properties->uri, &row); + if (info->fields_mask & EV_DOCUMENT_INFO_SUBJECT) { + set_property (properties, GTK_TABLE (table), SUBJECT_PROPERTY, info->subject, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_AUTHOR) { + set_property (properties, GTK_TABLE (table), AUTHOR_PROPERTY, info->author, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_KEYWORDS) { + set_property (properties, GTK_TABLE (table), KEYWORDS_PROPERTY, info->keywords, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_PRODUCER) { + set_property (properties, GTK_TABLE (table), PRODUCER_PROPERTY, info->producer, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_CREATOR) { + set_property (properties, GTK_TABLE (table), CREATOR_PROPERTY, info->creator, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_CREATION_DATE) { + text = ev_document_misc_format_date (info->creation_date); + set_property (properties, GTK_TABLE (table), CREATION_DATE_PROPERTY, text, &row); + g_free (text); + } + if (info->fields_mask & EV_DOCUMENT_INFO_MOD_DATE) { + text = ev_document_misc_format_date (info->modified_date); + set_property (properties, GTK_TABLE (table), MOD_DATE_PROPERTY, text, &row); + g_free (text); + } + if (info->fields_mask & EV_DOCUMENT_INFO_FORMAT) { + set_property (properties, GTK_TABLE (table), FORMAT_PROPERTY, info->format, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_N_PAGES) { + text = g_strdup_printf ("%d", info->n_pages); + set_property (properties, GTK_TABLE (table), N_PAGES_PROPERTY, text, &row); + g_free (text); + } + if (info->fields_mask & EV_DOCUMENT_INFO_LINEARIZED) { + set_property (properties, GTK_TABLE (table), LINEARIZED_PROPERTY, info->linearized, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_SECURITY) { + set_property (properties, GTK_TABLE (table), SECURITY_PROPERTY, info->security, &row); + } + if (info->fields_mask & EV_DOCUMENT_INFO_PAPER_SIZE) { + text = ev_regular_paper_size (info); + set_property (properties, GTK_TABLE (table), PAPER_SIZE_PROPERTY, text, &row); + g_free (text); + } +} + +static void +ev_properties_view_init (EvPropertiesView *properties) +{ + properties->table = gtk_table_new (13, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (properties->table), 12); + gtk_table_set_row_spacings (GTK_TABLE (properties->table), 6); + gtk_container_set_border_width (GTK_CONTAINER (properties->table), 12); + gtk_box_pack_start (GTK_BOX (properties), properties->table, + TRUE, TRUE, 0); + gtk_widget_show (properties->table); +} + +void +ev_properties_view_register_type (GTypeModule *module) +{ + ev_properties_view_get_type (); +} + +GtkWidget * +ev_properties_view_new (const gchar *uri) +{ + EvPropertiesView *properties; + + properties = g_object_new (EV_TYPE_PROPERTIES, NULL); + properties->uri = g_strdup (uri); + + return GTK_WIDGET (properties); +} diff --git a/properties/ev-properties-view.h b/properties/ev-properties-view.h new file mode 100644 index 00000000..e8e02649 --- /dev/null +++ b/properties/ev-properties-view.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ +/* this file is part of evince, a mate document viewer + * + * Copyright (C) 2005 Red Hat, Inc + * + * Evince 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 of the License, or + * (at your option) any later version. + * + * Evince 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __EV_PROPERTIES_VIEW_H__ +#define __EV_PROPERTIES_VIEW_H__ + +#include <gtk/gtk.h> + +#include <evince-document.h> + +G_BEGIN_DECLS + +typedef struct _EvPropertiesView EvPropertiesView; +typedef struct _EvPropertiesViewClass EvPropertiesViewClass; +typedef struct _EvPropertiesViewPrivate EvPropertiesViewPrivate; + +#define EV_TYPE_PROPERTIES (ev_properties_view_get_type()) +#define EV_PROPERTIES_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PROPERTIES, EvPropertiesView)) +#define EV_PROPERTIES_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PROPERTIES, EvPropertiesViewClass)) +#define EV_IS_PROPERTIES_VIEW(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PROPERTIES)) +#define EV_IS_PROPERTIES_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_PROPERTIES)) +#define EV_PROPERTIES_VIEW_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_PROPERTIES, EvPropertiesViewClass)) + +GType ev_properties_view_get_type (void); +void ev_properties_view_register_type (GTypeModule *module); + +GtkWidget *ev_properties_view_new (const gchar *uri); +void ev_properties_view_set_info (EvPropertiesView *properties, + const EvDocumentInfo *info); + +G_END_DECLS + +#endif /* __EV_PROPERTIES_VIEW_H__ */ |