+Wed Jan 19 01:10:57 2005 Jonathan Blandford <jrb@redhat.com>
+
+ * backend/Makefile.am:
+ * backend/ev-document-links.h:
+ * backend/ev-document-security.c: (ev_document_security_get_type),
+ (ev_document_security_has_document_security),
+ (ev_document_security_set_password):
+ * backend/ev-document-security.h:
+ * backend/ev-document.c: (ev_document_error_quark):
+ * backend/ev-document.h:
+ * data/Makefile.am:
+ * data/evince-password.glade:
+ * pdf/xpdf/pdf-document.cc:
+ * shell/Makefile.am:
+ * shell/ev-password.c: (ev_password_set_bad_password_label),
+ (ev_window_password_entry_changed_cb), (ev_password_dialog_new),
+ (ev_password_dialog_get_password),
+ (ev_password_dialog_set_bad_pass):
+ * shell/ev-password.h:
+ * shell/ev-window.c: (ev_window_get_attribute),
+ (ev_window_set_property), (update_action_sensitivity),
+ (ev_window_is_empty), (mime_type_supported_by_gdk_pixbuf),
+ (ev_window_setup_document), (ev_window_get_password),
+ (ev_window_open), (ev_window_cmd_save_as),
+ (using_postscript_printer), (ev_window_print),
+ (find_not_supported_dialog), (ev_window_cmd_edit_find),
+ (update_fullscreen_popup), (ev_window_fullscreen),
+ (ev_window_unfullscreen), (ev_window_cmd_view_fullscreen),
+ (ev_window_focus_out_cb), (ev_window_cmd_help_about),
+ (menu_item_select_cb), (find_bar_search_changed_cb),
+ (ev_window_dispose), (ev_window_init):
+
+ Add initial support for password-supported dialogs. This could be
+ a lot cooler, but it'll do for now.
+
2005-01-18 Marco Pesenti Gritti <marco@gnome.org>
* pdf/xpdf/pdf-document.cc:
ev-document-thumbnails.h \
ev-document-links.c \
ev-document-links.h \
+ ev-document-security.c \
+ ev-document-security.h \
ev-document-find.c \
ev-document-find.h \
ev-ps-exporter.c \
/* ev-document-links.h
- * this file is part of evince, a gnome document_links viewer
+ * this file is part of evince, a gnome document viewer
*
* Copyright (C) 2004 Red Hat, Inc.
*
--- /dev/null
+/* ev-document-links.h
+ * this file is part of evince, a gnome document_links viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author:
+ * Jonathan Blandford <jrb@alum.mit.edu>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ev-document-security.h"
+
+GType
+ev_document_security_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EvDocumentSecurityIface),
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "EvDocumentSecurity",
+ &our_info, (GTypeFlags)0);
+ }
+
+ return type;
+}
+
+gboolean
+ev_document_security_has_document_security (EvDocumentSecurity *document_security)
+{
+ EvDocumentSecurityIface *iface = EV_DOCUMENT_SECURITY_GET_IFACE (document_security);
+ return iface->has_document_security (document_security);
+}
+
+void
+ev_document_security_set_password (EvDocumentSecurity *document_security,
+ const char *password)
+{
+ EvDocumentSecurityIface *iface = EV_DOCUMENT_SECURITY_GET_IFACE (document_security);
+ iface->set_password (document_security, password);
+}
--- /dev/null
+/* ev-document-security.h
+ * this file is part of evince, a gnome pdf viewer
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Author:
+ * Jonathan Blandford <jrb@alum.mit.edu>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_DOCUMENT_SECURITY_H
+#define EV_DOCUMENT_SECURITY_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+
+#define EV_TYPE_DOCUMENT_SECURITY (ev_document_security_get_type ())
+#define EV_DOCUMENT_SECURITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_SECURITY, EvDocumentSecurity))
+#define EV_DOCUMENT_SECURITY_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_SECURITY, EvDocumentSecurityIface))
+#define EV_IS_DOCUMENT_SECURITY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_SECURITY))
+#define EV_IS_DOCUMENT_SECURITY_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_SECURITY))
+#define EV_DOCUMENT_SECURITY_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_SECURITY, EvDocumentSecurityIface))
+
+typedef struct _EvDocumentSecurity EvDocumentSecurity;
+typedef struct _EvDocumentSecurityIface EvDocumentSecurityIface;
+
+struct _EvDocumentSecurityIface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gboolean (* has_document_security) (EvDocumentSecurity *document_security);
+ void (* set_password) (EvDocumentSecurity *document_security,
+ const char *password);
+};
+
+GType ev_document_security_get_type (void);
+gboolean ev_document_security_has_document_security (EvDocumentSecurity *document_security);
+void ev_document_security_set_password (EvDocumentSecurity *document_security,
+ const char *password);
+
+G_END_DECLS
+
+#endif
return type;
}
+GQuark
+ev_document_error_quark (void)
+{
+ static GQuark q = 0;
+ if (q == 0)
+ q = g_quark_from_static_string ("ev-document-error-quark");
+
+ return q;
+}
+
static void
ev_document_class_init (gpointer g_class)
{
typedef struct _EvDocument EvDocument;
typedef struct _EvDocumentIface EvDocumentIface;
+#define EV_DOCUMENT_ERROR ev_document_error_quark ()
+
+typedef enum
+{
+ EV_DOCUMENT_ERROR_INVALID,
+ EV_DOCUMENT_ERROR_ENCRYPTED
+} EvDocumentError;
+
struct _EvDocumentIface
{
GTypeInterface base_iface;
int clip_y,
int clip_width,
int clip_height);
+
+
};
-GType ev_document_get_type (void);
+GType ev_document_get_type (void);
+GQuark ev_document_error_quark (void);
gboolean ev_document_load (EvDocument *document,
const char *uri,
evince-ui.xml \
$(NULL)
+gladedir = $(pkgdatadir)
+glade_DATA = \
+ evince-password.glade \
+ $(NULL)
+
stockdir = $(datadir)/pixmaps/evince
stock_DATA = \
ev-stock-zoom-fit-width.png \
EXTRA_DIST = \
$(stock_DATA) \
+ $(glade_DATA) \
$(ui_DATA) \
$(NULL)
--- /dev/null
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="password_dialog">
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes"></property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="ok_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-authentication</property>
+ <property name="icon_size">6</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkLabel" id="password_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">3</property>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Password:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">password_entry</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="password_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">False</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="bad_password_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><span size="smaller"> </span></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">1</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
#include "gpdf-g-switch.h"
#include "ev-document-links.h"
#include "ev-document-misc.h"
+#include "ev-document-security.h"
#include "ev-document-thumbnails.h"
#include "GlobalParams.h"
#include "SplashBitmap.h"
#include "PDFDoc.h"
#include "Outline.h"
+#include "ErrorCodes.h"
#include "UnicodeMap.h"
#include "GlobalParams.h"
#include "GfxState.h"
Links *links;
UnicodeMap *umap;
+ gchar *password;
gboolean page_valid;
PdfDocumentSearch *search;
};
-static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface);
+static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface);
static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
static void pdf_document_document_iface_init (EvDocumentIface *iface);
-static void pdf_document_ps_exporter_iface_init (EvPSExporterIface *iface);
-static void pdf_document_find_iface_init (EvDocumentFindIface *iface);
-static void pdf_document_search_free (PdfDocumentSearch *search);
-static void pdf_document_search_page_changed (PdfDocumentSearch *search);
+static void pdf_document_ps_exporter_iface_init (EvPSExporterIface *iface);
+static void pdf_document_find_iface_init (EvDocumentFindIface *iface);
+static void pdf_document_security_iface_init (EvDocumentSecurityIface *iface);
+static void pdf_document_search_free (PdfDocumentSearch *search);
+static void pdf_document_search_page_changed (PdfDocumentSearch *search);
+
G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
{
pdf_document_ps_exporter_iface_init);
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
pdf_document_find_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
+ pdf_document_security_iface_init);
});
static void
g_free (filename);
// open the PDF file, assumes ownership of filename_g
- newDoc = new PDFDoc(filename_g, 0, 0);
+ GString *password = NULL;
+ if (pdf_document->password)
+ password = new GString (pdf_document->password);
+ newDoc = new PDFDoc(filename_g, password, password);
+ if (password)
+ delete password;
if (!newDoc->isOk()) {
err = newDoc->getErrorCode();
delete newDoc;
-
- /* FIXME: Add a real error enum to EvDocument */
- g_set_error (error, G_FILE_ERROR,
- G_FILE_ERROR_FAILED,
- "Failed to load document (error %d) '%s'\n",
- err,
- uri);
+ if (err == errEncrypted) {
+ g_set_error (error, EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_ENCRYPTED,
+ "Document is encrypted.");
+ } else {
+ g_set_error (error, G_FILE_ERROR,
+ G_FILE_ERROR_FAILED,
+ "Failed to load document (error %d) '%s'\n",
+ err,
+ uri);
+ }
return FALSE;
}
g_free (search);
}
+static gboolean
+pdf_document_has_document_security (EvDocumentSecurity *document_security)
+{
+ /* FIXME: do we really need to have this? */
+ return FALSE;
+}
+
+static void
+pdf_document_set_password (EvDocumentSecurity *document_security,
+ const char *password)
+{
+ PdfDocument *document = PDF_DOCUMENT (document_security);
+
+ if (document->password)
+ g_free (document->password);
+
+ document->password = g_strdup (password);
+}
+
static void
pdf_document_ps_export_begin (EvPSExporter *exporter, const char *filename)
{
iface->cancel = pdf_document_find_cancel;
}
+static void
+pdf_document_security_iface_init (EvDocumentSecurityIface *iface)
+{
+ iface->has_document_security = pdf_document_has_document_security;
+ iface->set_password = pdf_document_set_password;
+}
+
static void
pdf_document_document_links_iface_init (EvDocumentLinksIface *iface)
{
pdf_document->scale = 1.;
pdf_document->page_valid = FALSE;
+ pdf_document->password = NULL;
}
ev-navigation-action.h \
ev-page-action.c \
ev-page-action.h \
+ ev-password.h \
+ ev-password.c \
ev-print-job.c \
ev-print-job.h \
ev-utils.c \
--- /dev/null
+/* this file is part of evince, a gnome 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ev-password.h"
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#define EV_PASSWORD_DATA "ev-password-data"
+
+static void
+ev_password_set_bad_password_label (GtkWidget *password,
+ gchar *message)
+{
+ GladeXML *xml;
+ GtkWidget *label;
+ gchar *markup;
+
+ xml = g_object_get_data (G_OBJECT (password), EV_PASSWORD_DATA);
+ g_assert (xml);
+
+ label = glade_xml_get_widget (xml, "bad_password_label");
+ markup = g_strdup_printf ("<span color=\"red\" size=\"smaller\">%s</span>",
+ message);
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ g_free (markup);
+}
+
+static void
+ev_window_password_entry_changed_cb (GtkEditable *editable,
+ GtkWidget *password)
+{
+ const char *text;
+ GtkWidget *button;
+ GladeXML *xml;
+
+ xml = g_object_get_data (G_OBJECT (password), EV_PASSWORD_DATA);
+ g_assert (xml);
+
+ text = gtk_entry_get_text (GTK_ENTRY (editable));
+ button = glade_xml_get_widget (xml, "ok_button");
+
+ if (text == NULL || *text == '\0')
+ gtk_widget_set_sensitive (button, FALSE);
+ else
+ gtk_widget_set_sensitive (button, TRUE);
+
+ ev_password_set_bad_password_label (password, " ");
+}
+
+GtkWidget *
+ev_password_dialog_new (GtkWidget *toplevel,
+ const char *uri)
+{
+ const char *glade_file = DATADIR "/evince-password.glade";
+ GladeXML *xml;
+ GtkWidget *dialog, *label;
+ GtkWidget *entry;
+ char *format;
+ char *markup;
+
+ xml = glade_xml_new (glade_file, NULL, NULL);
+ if (xml == NULL) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("Unable to find glade file"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("The glade file, %s, cannot be found. Please check that your installation is complete."),
+ glade_file);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ return NULL;
+ }
+
+ dialog = glade_xml_get_widget (xml, "password_dialog");
+ label = glade_xml_get_widget (xml, "password_label");
+ entry = glade_xml_get_widget (xml, "password_entry");
+
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
+ g_signal_connect (entry, "changed", G_CALLBACK (ev_window_password_entry_changed_cb), dialog);
+ format = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
+ _("Password required"),
+ _("The document '%s' requires a password before it can be opened."));
+ markup = g_markup_printf_escaped (format, uri);
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ g_free (format);
+ g_free (markup);
+
+ g_object_set_data_full (G_OBJECT (dialog), EV_PASSWORD_DATA, xml, g_object_unref);
+ ev_password_set_bad_password_label (dialog, " ");
+
+ return dialog;
+}
+
+char *
+ev_password_dialog_get_password (GtkWidget *password)
+{
+ GladeXML *xml;
+ GtkWidget *entry;
+
+ xml = g_object_get_data (G_OBJECT (password), EV_PASSWORD_DATA);
+ g_assert (xml);
+
+ entry = glade_xml_get_widget (xml, "password_entry");
+
+ return g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
+void
+ev_password_dialog_set_bad_pass (GtkWidget *password)
+{
+ GladeXML *xml;
+ GtkWidget *entry;
+
+ xml = g_object_get_data (G_OBJECT (password), EV_PASSWORD_DATA);
+ g_assert (xml);
+
+ entry = glade_xml_get_widget (xml, "password_entry");
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+ ev_password_set_bad_password_label (password, _("Incorrect password"));
+}
--- /dev/null
+/* this file is part of evince, a gnome 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EV_PASSWORD_H__
+#define __EV_PASSWORD_H__
+
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+GtkWidget *ev_password_dialog_new (GtkWidget *toplevel,
+ const gchar *uri);
+char *ev_password_dialog_get_password (GtkWidget *password);
+void ev_password_dialog_set_bad_pass (GtkWidget *password);
+
+G_END_DECLS
+
+#endif /* __EV_PASSWORD_H__ */
#include "ev-sidebar-links.h"
#include "ev-sidebar-thumbnails.h"
#include "ev-view.h"
+#include "ev-password.h"
#include "ev-print-job.h"
#include "ev-document-find.h"
+#include "ev-document-security.h"
#include "eggfindbar.h"
#include "pdf-document.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <libgnomeprintui/gnome-print-dialog.h>
ev_window_get_attribute (EvWindow *self)
{
g_return_val_if_fail (self != NULL && EV_IS_WINDOW (self), NULL);
-
+
return self->priv->attribute;
}
GParamSpec *param_spec)
{
EvWindow *self;
-
+
self = EV_WINDOW (object);
-
+
switch (prop_id) {
case PROP_ATTRIBUTE:
ev_window_set_attribute (self, g_value_get_string (value));
set_action_sensitive (ev_window, "GoPageUp", FALSE);
set_action_sensitive (ev_window, "GoLastPage", FALSE);
}
-
+
/* Help menu */
/* "HelpContents": always sensitive */
/* "HelpAbout": always sensitive */
ev_window_is_empty (const EvWindow *ev_window)
{
g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
-
+
return ev_window->priv->document == NULL;
}
{
GSList *formats, *list;
gboolean retval = FALSE;
-
+
formats = gdk_pixbuf_get_formats ();
-
+
list = formats;
while (list) {
GdkPixbufFormat *format = list->data;
int i;
gchar **mime_types;
-
+
if (gdk_pixbuf_format_is_disabled (format))
continue;
mime_types = gdk_pixbuf_format_get_mime_types (format);
-
+
for (i = 0; mime_types[i] != NULL; i++) {
if (strcmp (mime_types[i], mime_type) == 0) {
retval = TRUE;
break;
}
}
-
+
if (retval)
break;
-
+
list = list->next;
}
-
+
g_slist_free (formats);
return retval;
ev_page_action_set_total_pages (EV_PAGE_ACTION (action), pages);
}
+/* This function assumes that ev_window just had ev_window->document set.
+ */
+static void
+ev_window_setup_document (EvWindow *ev_window)
+{
+ EvDocument *document;
+ EvHistory *history;
+ EvView *view = EV_VIEW (ev_window->priv->view);
+ EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar);
+ GtkAction *action;
+
+ document = ev_window->priv->document;
+
+ ev_view_set_document (view, document);
+ ev_sidebar_set_document (sidebar, document);
+
+ history = ev_history_new ();
+ ev_view_set_history (view, history);
+ g_object_unref (history);
+
+ action = gtk_action_group_get_action
+ (ev_window->priv->action_group, NAVIGATION_BACK_ACTION);
+ ev_navigation_action_set_history
+ (EV_NAVIGATION_ACTION (action), history);
+
+ action = gtk_action_group_get_action
+ (ev_window->priv->action_group, NAVIGATION_FORWARD_ACTION);
+ ev_navigation_action_set_history
+ (EV_NAVIGATION_ACTION (action), history);
+
+ update_total_pages (ev_window);
+ update_action_sensitivity (ev_window);
+}
+
+
+static gchar *
+ev_window_get_password (GtkWidget *password_dialog)
+{
+ gchar *password = NULL;
+
+ if (gtk_dialog_run (GTK_DIALOG (password_dialog)) == GTK_RESPONSE_OK)
+ password = ev_password_dialog_get_password (password_dialog);
+
+ return password;
+}
+
void
ev_window_open (EvWindow *ev_window, const char *uri)
{
EvDocument *document = NULL;
char *mime_type;
-
+
g_free (ev_window->priv->uri);
ev_window->priv->uri = g_strdup (uri);
document = g_object_new (PS_TYPE_DOCUMENT, NULL);
else if (mime_type_supported_by_gdk_pixbuf (mime_type))
document = g_object_new (PIXBUF_TYPE_DOCUMENT, NULL);
-
+
if (document) {
GError *error = NULL;
+ GtkWidget *password_dialog = NULL;
g_signal_connect_object (G_OBJECT (document),
"notify::title",
G_CALLBACK (update_window_title),
ev_window, 0);
- if (ev_document_load (document, uri, &error)) {
- EvHistory *history;
- EvView *view = EV_VIEW (ev_window->priv->view);
- EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar);
- GtkAction *action;
-
- if (ev_window->priv->document)
- g_object_unref (ev_window->priv->document);
- ev_window->priv->document = document;
+ /* If we get an error while loading the document, we try to fix
+ * it and try again. This is an ugly loop that could do with
+ * some refactoring.*/
+ while (TRUE) {
+ gboolean result;
- ev_view_set_document (view, document);
- ev_sidebar_set_document (sidebar, document);
+ result = ev_document_load (document, uri, &error);
- history = ev_history_new ();
- ev_view_set_history (view, history);
- g_object_unref (history);
+ if (result) {
+ if (ev_window->priv->document)
+ g_object_unref (ev_window->priv->document);
+ ev_window->priv->document = document;
+ ev_window_setup_document (ev_window);
- action = gtk_action_group_get_action
- (ev_window->priv->action_group, NAVIGATION_BACK_ACTION);
- ev_navigation_action_set_history
- (EV_NAVIGATION_ACTION (action), history);
-
- action = gtk_action_group_get_action
- (ev_window->priv->action_group, NAVIGATION_FORWARD_ACTION);
- ev_navigation_action_set_history
- (EV_NAVIGATION_ACTION (action), history);
+ if (password_dialog)
+ gtk_widget_destroy (password_dialog);
+ break;
+ }
- update_total_pages (ev_window);
- update_action_sensitivity (ev_window);
- } else {
g_assert (error != NULL);
+
+ if (error->domain == EV_DOCUMENT_ERROR &&
+ error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
+ char *password;
+
+ if (password_dialog == NULL)
+ password_dialog = ev_password_dialog_new (GTK_WIDGET (ev_window), uri);
+ else
+ ev_password_dialog_set_bad_pass (password_dialog);
+ password = ev_window_get_password (password_dialog);
+ if (password) {
+ ev_document_security_set_password (EV_DOCUMENT_SECURITY (document),
+ password);
+ g_free (password);
+ g_error_free (error);
+ error = NULL;
+ continue;
+ } else {
+ gtk_widget_destroy (password_dialog);
+ }
+ } else {
+ unable_to_load (ev_window, error->message);
+ }
g_object_unref (document);
- unable_to_load (ev_window, error->message);
g_error_free (error);
+ break;
}
} else {
char *error_message;
GTK_MESSAGE_DIALOG (msgbox),
_("Do you want to replace it with the one you are saving?"));
- gtk_dialog_add_button (GTK_DIALOG (msgbox),
+ gtk_dialog_add_button (GTK_DIALOG (msgbox),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_dialog_add_button (GTK_DIALOG (msgbox),
{
GtkWidget *fc;
GtkFileFilter *pdf_filter, *all_filter;
- gchar *uri = NULL;
+ gchar *uri = NULL;
fc = gtk_file_chooser_dialog_new (
_("Save a Copy"),
gtk_file_filter_add_pattern (all_filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), all_filter);
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (fc), pdf_filter);
-
+
gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
gtk_widget_show (fc);
uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
/* FIXME
- if (g_file_test (uri, G_FILE_TEST_EXISTS) &&
+ if (g_file_test (uri, G_FILE_TEST_EXISTS) &&
!overwrite_existing_file (GTK_WINDOW (fc), uri))
continue;
*/
if (ev_document_save (ev_window->priv->document, uri, NULL))
break;
else
- save_error_dialog (GTK_WINDOW (fc), uri);
+ save_error_dialog (GTK_WINDOW (fc), uri);
}
gtk_widget_destroy (fc);
}
driver = gnome_print_config_get (
config, (const guchar *)"Settings.Engine.Backend.Driver");
-
+
transport = gnome_print_config_get (
config, (const guchar *)"Settings.Transport.Backend");
-
+
if (driver) {
if (!strcmp ((const gchar *)driver, "gnome-print-ps"))
return TRUE;
- else
+ else
return FALSE;
} else if (transport) {
if (!strcmp ((const gchar *)transport, "CUPS"))
return TRUE;
}
-
+
return FALSE;
}
gtk_dialog_set_response_sensitive (GTK_DIALOG (print_dialog),
GNOME_PRINT_DIALOG_RESPONSE_PREVIEW,
FALSE);
-
+
while (TRUE) {
int response;
response = gtk_dialog_run (GTK_DIALOG (print_dialog));
-
+
if (response != GNOME_PRINT_DIALOG_RESPONSE_PRINT)
break;
*/
if (!using_postscript_printer (config)) {
GtkWidget *dialog;
-
+
dialog = gtk_message_dialog_new (
GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
NULL);
break;
}
-
+
gtk_widget_destroy (print_dialog);
if (print_job != NULL) {
/* If you change this so it isn't modal, be sure you don't
* allow multiple copies of the dialog...
*/
-
+
dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
} else {
gtk_widget_show (ev_window->priv->find_bar);
- if (ev_window->priv->exit_fullscreen_popup)
+ if (ev_window->priv->exit_fullscreen_popup)
update_fullscreen_popup (ev_window);
-
+
egg_find_bar_grab_focus (EGG_FIND_BAR (ev_window->priv->find_bar));
}
}
if (!popup)
return;
-
+
popup_width = popup->requisition.width;
popup_height = popup->requisition.height;
GtkRequisition req;
gtk_widget_size_request (window->priv->find_bar, &req);
-
+
screen_rect.height -= req.height;
}
-
+
if (gtk_widget_get_direction (popup) == GTK_TEXT_DIR_RTL)
{
gtk_window_move (GTK_WINDOW (popup),
main_menu = gtk_ui_manager_get_widget (window->priv->ui_manager, "/MainMenu");
gtk_widget_hide (main_menu);
gtk_widget_hide (window->priv->statusbar);
-
+
update_fullscreen_popup (window);
gtk_widget_show (popup);
ev_window_unfullscreen (EvWindow *window)
{
GtkWidget *main_menu;
-
+
window->priv->fullscreen_mode = FALSE;
main_menu = gtk_ui_manager_get_widget (window->priv->ui_manager, "/MainMenu");
gtk_widget_show (main_menu);
gtk_widget_show (window->priv->statusbar);
-
+
destroy_exit_fullscreen_popup (window);
}
-
+
static void
ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *ev_window)
{
gboolean fullscreen;
-
+
g_return_if_fail (EV_IS_WINDOW (ev_window));
fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
ev_window_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *ev_window)
{
gtk_window_unfullscreen (GTK_WINDOW (ev_window));
-
+
return FALSE;
}
N_("Evince is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
"the Free Software Foundation; either version 2 of the License, or\n"
- "(at your option) any later version.\n"),
+ "(at your option) any later version.\n"),
N_("Evince is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
action = g_object_get_data (G_OBJECT (proxy), "gtk-action");
g_return_if_fail (action != NULL);
-
+
g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
if (message) {
gtk_statusbar_push (GTK_STATUSBAR (ev_window->priv->statusbar),
const char *search_string;
g_return_if_fail (EV_IS_WINDOW (ev_window));
-
+
/* Either the string or case sensitivity could have changed,
* we connect this callback to both. We also connect it
* to ::visible so when the find bar is hidden, we should
case_sensitive = egg_find_bar_get_case_sensitive (find_bar);
visible = GTK_WIDGET_VISIBLE (find_bar);
search_string = egg_find_bar_get_search_string (find_bar);
-
+
#if 0
g_printerr ("search for '%s'\n", search_string ? search_string : "(nil)");
#endif
g_object_unref (priv->action_group);
priv->action_group = NULL;
}
-
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
G_CALLBACK (ev_window_cmd_edit_copy) },
{ "EditSelectAll", NULL, N_("Select _All"), "<control>A",
N_("Select the entire page"),
- G_CALLBACK (ev_window_cmd_edit_select_all) },
+ G_CALLBACK (ev_window_cmd_edit_select_all) },
{ "EditFind", GTK_STOCK_FIND, N_("_Find"), "<control>F",
N_("Find a word or phrase in the document"),
G_CALLBACK (ev_window_cmd_edit_find) },
G_CALLBACK (ev_window_cmd_go_page_down) },
{ "GoFirstPage", GTK_STOCK_GOTO_FIRST, N_("_First Page"), "<control>Home",
N_("Go to the first page"),
- G_CALLBACK (ev_window_cmd_go_first_page) },
+ G_CALLBACK (ev_window_cmd_go_first_page) },
{ "GoLastPage", GTK_STOCK_GOTO_LAST, N_("_Last Page"), "<control>End",
N_("Go to the last page"),
G_CALLBACK (ev_window_cmd_go_last_page) },
-
+
/* Help menu */
{ "HelpContents", GTK_STOCK_HELP, N_("_Contents"), NULL,
N_("Display help for the viewer application"),
G_CALLBACK (ev_window_cmd_help_contents) },
-
+
{ "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL,
N_("Display credits for the document viewer creators"),
G_CALLBACK (ev_window_cmd_help_about) },
ev_window->priv->main_box = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (ev_window), ev_window->priv->main_box);
gtk_widget_show (ev_window->priv->main_box);
-
+
action_group = gtk_action_group_new ("MenuActions");
ev_window->priv->action_group = action_group;
gtk_action_group_set_translation_domain (action_group, NULL);
"thumbnails",
_("Thumbnails"),
sidebar_widget);
-
+
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled_window);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box),
ev_window->priv->find_bar,
FALSE, TRUE, 0);
-
+
/* Connect to find bar signals */
g_signal_connect (ev_window->priv->find_bar,
"previous",
g_signal_connect (ev_window, "focus_out_event",
G_CALLBACK (ev_window_focus_out_cb),
ev_window);
-
+
/* Give focus to the scrolled window */
gtk_widget_grab_focus (scrolled_window);
-
+
update_action_sensitivity (ev_window);
-}
+}