summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Scorgie <dscorgie@cvs.gnome.org>2005-12-11 22:28:54 +0000
committerDon Scorgie <dscorgie@src.gnome.org>2005-12-11 22:28:54 +0000
commitb4211bf00eecfed75260d1e8447adbfe9b6384be (patch)
tree698a77076302351acbe14617ba7024dac26fd8b6
parent3a2985a5a4e5ac67937c7650d469e1acc854c6b3 (diff)
downloadyelp-b4211bf00eecfed75260d1e8447adbfe9b6384be.tar.gz
Add printing support
2005-12-11 Don Scorgie <dscorgie@cvs.gnome.org> * configure.in: * data/ui/yelp-ui.xml: * src/Makefile.am: * src/Yelper.h: * src/Yelper.cpp: * src/yelp-db-print-pager.h: * src/yelp-db-print-pager.c: * src/yelp-gecko-services.h: * src/yelp-gecko-services.cpp: * src/yelp-html.cpp: * src/yelp-html.h: * src/yelp-main.c: * src/yelp-print.c: * src/yelp-print.h: * src/yelp-window.c: Add printing support
-rw-r--r--ChangeLog19
-rw-r--r--configure.in2
-rw-r--r--data/ui/yelp-ui.xml3
-rw-r--r--src/Makefile.am13
-rw-r--r--src/Yelper.cpp254
-rw-r--r--src/Yelper.h10
-rw-r--r--src/yelp-db-print-pager.c295
-rw-r--r--src/yelp-db-print-pager.h55
-rw-r--r--src/yelp-gecko-services.cpp243
-rw-r--r--src/yelp-gecko-services.h80
-rw-r--r--src/yelp-html.cpp36
-rw-r--r--src/yelp-html.h11
-rw-r--r--src/yelp-main.c7
-rw-r--r--src/yelp-print.c743
-rw-r--r--src/yelp-print.h90
-rw-r--r--src/yelp-window.c285
16 files changed, 2140 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 19634787..30ec9407 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2005-12-11 Don Scorgie <dscorgie@cvs.gnome.org>
+
+ * configure.in:
+ * data/ui/yelp-ui.xml:
+ * src/Makefile.am:
+ * src/Yelper.h:
+ * src/Yelper.cpp:
+ * src/yelp-db-print-pager.h:
+ * src/yelp-db-print-pager.c:
+ * src/yelp-gecko-services.h:
+ * src/yelp-gecko-services.cpp:
+ * src/yelp-html.cpp:
+ * src/yelp-html.h:
+ * src/yelp-main.c:
+ * src/yelp-print.c:
+ * src/yelp-print.h:
+ * src/yelp-window.c:
+ Add printing support
+
2005-12-11 Brent Smith <gnome@nextreality.net>
* src/yelp-toc-pager.c: (yelp_toc_pager_init),
diff --git a/configure.in b/configure.in
index 9d14c2aa..d242cb56 100644
--- a/configure.in
+++ b/configure.in
@@ -65,6 +65,8 @@ PKG_CHECK_MODULES(YELP,
[
gconf-2.0
gnome-doc-utils >= 0.3.1
+ libgnomeprint-2.2
+ libgnomeprintui-2.2
gnome-vfs-2.0 >= 1.1
gtk+-2.0 >= 2.5.3
libbonobo-2.0 >= 1.108.0
diff --git a/data/ui/yelp-ui.xml b/data/ui/yelp-ui.xml
index b91a5e00..ea2c4abb 100644
--- a/data/ui/yelp-ui.xml
+++ b/data/ui/yelp-ui.xml
@@ -6,6 +6,9 @@
<separator/>
<menuitem action="AboutDocument"/>
<separator/>
+ <menuitem action="PrintPage"/>
+ <menuitem action="PrintDocument"/>
+ <separator/>
<menuitem action="CloseWindow"/>
</menu>
<menu action="EditMenu">
diff --git a/src/Makefile.am b/src/Makefile.am
index 568032e4..4579779b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ yelp_SOURCES = \
yelp-bookmarks.c yelp-bookmarks.h \
yelp-cache.c yelp-cache.h \
yelp-db-pager.c yelp-db-pager.h \
+ yelp-db-print-pager.c yelp-db-print-pager.h \
yelp-error.c yelp-error.h \
yelp-gecko-utils.cpp yelp-gecko-utils.h \
yelp-html.cpp yelp-html.h \
@@ -19,7 +20,9 @@ yelp_SOURCES = \
yelp-utils.c yelp-utils.h \
yelp-window.c yelp-window.h \
yelp-xslt-pager.c yelp-xslt-pager.h \
- yelp-marshal-main.c yelp-main.c
+ yelp-marshal-main.c yelp-main.c \
+ yelp-print.c yelp-print.h \
+ yelp-gecko-services.h yelp-gecko-services.cpp
if ENABLE_MAN
yelp_SOURCES += \
@@ -61,7 +64,12 @@ mozilla_include_subdirs = \
webbrwsr \
string \
webshell \
- commandhandler
+ commandhandler \
+ layout \
+ uriloader \
+ content \
+ gfx \
+ necko
yelp_CPPFLAGS = \
-I$(top_srcdir) \
@@ -114,6 +122,7 @@ test_man_parser_LDFLAGS = $(AM_LDFLAGS)
test_pager_SOURCES = \
yelp-db-pager.c yelp-db-pager.h \
+ yelp-db-print-pager.c yelp-db-print-pager.h \
yelp-error.c yelp-error.h \
yelp-io-channel.c yelp-io-channel.h \
yelp-man-pager.c yelp-man-pager.h \
diff --git a/src/Yelper.cpp b/src/Yelper.cpp
index de2f4f07..e18f1c92 100644
--- a/src/Yelper.cpp
+++ b/src/Yelper.cpp
@@ -43,6 +43,7 @@
#include <nsIDOMEventTarget.h>
#include <nsIDOMNode.h>
#include <nsIDOMHTMLAnchorElement.h>
+#include <nsIWebBrowserPrint.h>
#ifdef TYPEAHEADFIND
#include <nsIDocShell.h>
@@ -50,9 +51,12 @@
#endif /* TYPEAHEADFIND */
#include <stdlib.h>
+#include <unistd.h>
#include <gtkmozembed_internal.h>
+#include <yelp-gecko-services.h>
+
#ifdef GNOME_ENABLE_DEBUG
#define d(x) x
#else
@@ -254,3 +258,253 @@ Yelper::ProcessMouseEvent (void* aEvent)
g_signal_emit_by_name (mEmbed, "popupmenu_requested", cHref.get());
}
+
+nsresult
+Yelper::Print (YelpPrintInfo *print_info, PRBool preview, int *prev_pages)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface (mWebBrowser, &rv));
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ nsCOMPtr<nsIPrintSettings> settings;
+
+ rv = print->GetGlobalPrintSettings (getter_AddRefs (settings));
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ SetPrintSettings (print_info, settings);
+
+ nsCOMPtr<PrintListener> listener = new PrintListener (print_info, print);
+
+ if (!preview)
+ rv = print->Print (settings, listener);
+ else {
+ rv = print->PrintPreview (settings, mDOMWindow, nsnull);
+ rv |= print->GetPrintPreviewNumPages (prev_pages);
+ }
+ return rv;
+
+}
+
+nsresult
+Yelper::PrintPreviewNavigate (int page_no)
+{
+ nsresult rv;
+ nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface (mWebBrowser, &rv));
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ return print->PrintPreviewNavigate (0, page_no);
+}
+
+
+
+nsresult
+Yelper::PrintPreviewEnd ()
+{
+ nsresult rv;
+ nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface (mWebBrowser, &rv));
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ return print->ExitPrintPreview ();
+
+}
+
+void
+Yelper::SetPrintSettings (YelpPrintInfo *settings, nsIPrintSettings * target)
+{
+ char *base;
+ const char *temp_dir;
+ int fd;
+ const GnomePrintUnit *unit, *inch, *mm;
+ double value;
+ nsEmbedString tmp;
+
+ const static PRUnichar pName[] = { 'P', 'o', 's', 't', 'S', 'c', 'r', 'i', 'p', 't', '/', 'd', 'e', 'f', 'a', 'u', 'l', 't', '\0' };
+ target->SetPrinterName(nsEmbedString(pName).get());
+
+ const static int frame_types[] = {
+ nsIPrintSettings::kFramesAsIs,
+ nsIPrintSettings::kSelectedFrame,
+ nsIPrintSettings::kEachFrameSep
+ };
+
+ switch (settings->range)
+ {
+ case GNOME_PRINT_RANGE_CURRENT:
+ case GNOME_PRINT_RANGE_SELECTION_UNSENSITIVE:
+ case GNOME_PRINT_RANGE_ALL:
+ target->SetPrintRange (nsIPrintSettings::kRangeAllPages);
+ break;
+ case GNOME_PRINT_RANGE_RANGE:
+ target->SetPrintRange (nsIPrintSettings::kRangeSpecifiedPageRange);
+ target->SetStartPageRange (settings->from_page);
+ target->SetEndPageRange (settings->to_page);
+ break;
+ case GNOME_PRINT_RANGE_SELECTION:
+ target->SetPrintRange (nsIPrintSettings::kRangeSelection);
+ break;
+ }
+
+ mm = gnome_print_unit_get_by_abbreviation ((const guchar *) "mm");
+ inch = gnome_print_unit_get_by_abbreviation ((const guchar *) "in");
+ g_assert (mm != NULL && inch != NULL);
+
+ /* top margin */
+ if (gnome_print_config_get_length (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAGE_MARGIN_TOP,
+ &value, &unit)
+ && gnome_print_convert_distance (&value, unit, inch))
+ {
+ target->SetMarginTop (value);
+ }
+
+ /* bottom margin */
+ if (gnome_print_config_get_length (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM,
+ &value, &unit)
+ && gnome_print_convert_distance (&value, unit, inch))
+ {
+ target->SetMarginBottom (value);
+ }
+
+ /* left margin */
+ if (gnome_print_config_get_length (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAGE_MARGIN_LEFT,
+ &value, &unit)
+ && gnome_print_convert_distance (&value, unit, inch))
+ {
+ target->SetMarginLeft (value);
+ }
+
+ /* right margin */
+ if (gnome_print_config_get_length (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT,
+ &value, &unit)
+ && gnome_print_convert_distance (&value, unit, inch))
+ {
+ target->SetMarginRight (value);
+ }
+
+
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->header_left_string),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetHeaderStrLeft (tmp.get());
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->header_center_string),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetHeaderStrCenter (tmp.get());
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->header_right_string),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetHeaderStrRight (tmp.get());
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->footer_left_string),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetFooterStrLeft (tmp.get());
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->footer_center_string),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetFooterStrCenter(tmp.get());
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->footer_right_string),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetFooterStrRight(tmp.get());
+
+
+
+ temp_dir = g_get_tmp_dir ();
+ base = g_build_filename (temp_dir, "printXXXXXX", NULL);
+ fd = g_mkstemp (base);
+ close(fd);
+ settings->tempfile = g_strdup (base);
+
+ g_free (base);
+
+
+ NS_CStringToUTF16 (nsEmbedCString(settings->tempfile),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetPrintToFile (PR_TRUE);
+ target->SetToFileName (tmp.get());
+
+
+ /* paper size */
+ target->SetPaperSize (nsIPrintSettings::kPaperSizeDefined);
+ target->SetPaperSizeUnit (nsIPrintSettings::kPaperSizeMillimeters);
+
+ if (gnome_print_config_get_length (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAPER_WIDTH,
+ &value, &unit)
+ && gnome_print_convert_distance (&value, unit, mm))
+ {
+ target->SetPaperWidth (value);
+ }
+
+ if (gnome_print_config_get_length (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAPER_HEIGHT,
+ &value, &unit)
+ && gnome_print_convert_distance (&value, unit, mm))
+ {
+ target->SetPaperHeight (value);
+ }
+
+ /* Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=307404
+ * means that we cannot actually use any paper sizes except mozilla's
+ * builtin list, and we must refer to them *by name*!
+ */
+#ifndef HAVE_GECKO_1_9
+ /* Gnome-Print names some papers differently than what moz understands */
+ static const struct
+ {
+ const char *gppaper;
+ const char *mozpaper;
+ }
+ paper_table [] =
+ {
+ { "USLetter", "Letter" },
+ { "USLegal", "Legal" }
+ };
+#endif /* !HAVE_GECKO_1_9 */
+
+ /* paper name */
+ char *string = (char *) gnome_print_config_get (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_PAPER_SIZE);
+ const char *paper = string;
+
+#ifndef HAVE_GECKO_1_9
+ for (PRUint32 i = 0; i < G_N_ELEMENTS (paper_table); i++)
+ {
+ if (string != NULL &&
+ g_ascii_strcasecmp (paper_table[i].gppaper, string) == 0)
+ {
+ paper = paper_table[i].mozpaper;
+ break;
+ }
+ }
+#endif /* !HAVE_GECKO_1_9 */
+
+ NS_CStringToUTF16 (nsEmbedCString(paper),
+ NS_CSTRING_ENCODING_UTF8, tmp);
+ target->SetPaperName (tmp.get());
+ g_free (string);
+
+ /* paper orientation */
+ string = (char *) gnome_print_config_get (settings->config,
+ (const guchar *) GNOME_PRINT_KEY_ORIENTATION);
+ if (string == NULL) string = g_strdup ("R0");
+
+ if (strncmp (string, "R90", 3) == 0 || strncmp (string, "R270", 4) == 0)
+ {
+ target->SetOrientation (nsIPrintSettings::kLandscapeOrientation);
+ }
+ else
+ {
+ target->SetOrientation (nsIPrintSettings::kPortraitOrientation);
+ }
+ g_free (string);
+
+ target->SetPrintInColor (TRUE);
+ target->SetPrintFrameType (frame_types[settings->frame_type]);
+
+
+}
diff --git a/src/Yelper.h b/src/Yelper.h
index 9d0d9993..c7b5d48a 100644
--- a/src/Yelper.h
+++ b/src/Yelper.h
@@ -32,6 +32,8 @@
#else
#include <nsIWebBrowserFind.h>
#endif
+#include <nsIPrintSettings.h>
+#include <yelp-print.h>
class Yelper
{
@@ -52,6 +54,12 @@ public:
void ProcessMouseEvent (void *aEvent);
+ nsresult Print (YelpPrintInfo *print_info, PRBool preview,
+ int *prev_pages);
+ nsresult PrintPreviewNavigate (int page_no);
+ nsresult PrintPreviewEnd ();
+
+
private:
PRBool mInitialised;
GtkMozEmbed *mEmbed;
@@ -62,6 +70,8 @@ private:
#else
nsCOMPtr<nsIWebBrowserFind> mFinder;
#endif
+
+ void SetPrintSettings (YelpPrintInfo *settings, nsIPrintSettings *target);
};
#endif /* !__YELPER_H__ */
diff --git a/src/yelp-db-print-pager.c b/src/yelp-db-print-pager.c
new file mode 100644
index 00000000..8d8dcf7e
--- /dev/null
+++ b/src/yelp-db-print-pager.c
@@ -0,0 +1,295 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 Shaun McCance <shaunm@gnome.org>
+ *
+ * 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 of the
+ * License, 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.
+ *
+ * Author: Shaun McCance <shaunm@gnome.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xinclude.h>
+#include <libxslt/xslt.h>
+#include <libxslt/templates.h>
+#include <libxslt/transform.h>
+#include <libxslt/extensions.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+
+#include "yelp-error.h"
+#include "yelp-db-print-pager.h"
+#include "yelp-toc-pager.h"
+#include "yelp-settings.h"
+
+#ifdef YELP_DEBUG
+#define d(x) x
+#else
+#define d(x)
+#endif
+
+#define STYLESHEET_PATH DATADIR"/yelp/xslt/"
+#define DB_STYLESHEET STYLESHEET_PATH"db2html.xsl"
+#define DB_TITLE STYLESHEET_PATH"db-title.xsl"
+
+#define BOOK_CHUNK_DEPTH 2
+#define ARTICLE_CHUNK_DEPTH 1
+
+#define EVENTS_PENDING while (yelp_pager_get_state (pager) <= YELP_PAGER_STATE_RUNNING && gtk_events_pending ()) gtk_main_iteration ();
+#define CANCEL_CHECK if (!main_running || yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) goto done;
+
+extern gboolean main_running;
+
+#define YELP_DB_PRINT_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerPriv))
+
+struct _YelpDBPrintPagerPriv {
+ gchar *root_id;
+};
+
+static void db_print_pager_class_init (YelpDBPrintPagerClass *klass);
+static void db_print_pager_init (YelpDBPrintPager *pager);
+static void db_print_pager_dispose (GObject *gobject);
+
+static void db_print_pager_cancel (YelpPager *pager);
+static xmlDocPtr db_print_pager_parse (YelpPager *pager);
+static gchar ** db_print_pager_params (YelpPager *pager);
+
+static const gchar * db_print_pager_resolve_frag (YelpPager *pager,
+ const gchar *frag_id);
+static GtkTreeModel * db_print_pager_get_sections (YelpPager *pager);
+
+static YelpPagerClass *parent_class;
+
+GType
+yelp_db_print_pager_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (YelpDBPrintPagerClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) db_print_pager_class_init,
+ NULL,
+ NULL,
+ sizeof (YelpDBPrintPager),
+ 0,
+ (GInstanceInitFunc) db_print_pager_init,
+ };
+ type = g_type_register_static (YELP_TYPE_XSLT_PAGER,
+ "YelpDBPrintPager",
+ &info, 0);
+ }
+ return type;
+}
+
+static void
+db_print_pager_class_init (YelpDBPrintPagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass);
+ YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->dispose = db_print_pager_dispose;
+
+ pager_class->cancel = db_print_pager_cancel;
+
+ pager_class->resolve_frag = db_print_pager_resolve_frag;
+
+ xslt_class->parse = db_print_pager_parse;
+ xslt_class->params = db_print_pager_params;
+
+ xslt_class->stylesheet = DB_STYLESHEET;
+
+ g_type_class_add_private (klass, sizeof (YelpDBPrintPagerPriv));
+}
+
+static void
+db_print_pager_init (YelpDBPrintPager *pager)
+{
+ YelpDBPrintPagerPriv *priv;
+
+ pager->priv = priv = YELP_DB_PRINT_PAGER_GET_PRIVATE (pager);
+
+ pager->priv->root_id = NULL;
+}
+
+static void
+db_print_pager_dispose (GObject *object)
+{
+ YelpDBPrintPager *pager = YELP_DB_PRINT_PAGER (object);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+/******************************************************************************/
+
+YelpPager *
+yelp_db_print_pager_new (YelpDocInfo *doc_info)
+{
+ YelpDBPrintPager *pager;
+
+ g_return_val_if_fail (doc_info != NULL, NULL);
+
+ pager = (YelpDBPrintPager *) g_object_new (YELP_TYPE_DB_PRINT_PAGER,
+ "document-info", doc_info,
+ NULL);
+
+ return (YelpPager *) pager;
+}
+
+static xmlDocPtr
+db_print_pager_parse (YelpPager *pager)
+{
+ YelpDBPrintPagerPriv *priv;
+ YelpDocInfo *doc_info;
+ gchar *filename = NULL;
+
+ xmlParserCtxtPtr parserCtxt = NULL;
+ xmlDocPtr doc = NULL;
+
+ xmlChar *id;
+ GError *error = NULL;
+
+ d (g_print ("db_print_pager_parse\n"));
+
+ doc_info = yelp_pager_get_doc_info (pager);
+
+ g_return_val_if_fail (pager != NULL, NULL);
+ g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), NULL);
+ priv = YELP_DB_PRINT_PAGER (pager)->priv;
+
+ g_object_ref (pager);
+
+ if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR)
+ goto done;
+
+ filename = yelp_doc_info_get_filename (doc_info);
+
+ parserCtxt = xmlNewParserCtxt ();
+ doc = xmlCtxtReadFile (parserCtxt,
+ (const char *) filename, NULL,
+ XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
+ XML_PARSE_NOENT | XML_PARSE_NONET );
+ if (doc == NULL) {
+ g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_DOC,
+ _("The file ā€˜%sā€™ could not be parsed. Either the file "
+ "does not exist, or it is not well-formed XML."),
+ filename);
+ yelp_pager_error (pager, error);
+ goto done;
+ }
+
+ xmlXIncludeProcessFlags (doc,
+ XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
+ XML_PARSE_NOENT | XML_PARSE_NONET );
+
+
+ priv->root_id = g_strdup ("index");
+
+ EVENTS_PENDING;
+ CANCEL_CHECK;
+
+ done:
+ g_free (filename);
+
+ if (parserCtxt)
+ xmlFreeParserCtxt (parserCtxt);
+
+ g_object_unref (pager);
+
+ return doc;
+}
+
+static gchar **
+db_print_pager_params (YelpPager *pager)
+{
+ YelpDBPrintPagerPriv *priv;
+ YelpDocInfo *doc_info;
+ gchar **params;
+ gint params_i = 0;
+ gint params_max = 20;
+
+ d (g_print ("db_print_pager_process\n"));
+
+ doc_info = yelp_pager_get_doc_info (pager);
+
+ g_return_val_if_fail (pager != NULL, FALSE);
+ g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), FALSE);
+ priv = YELP_DB_PRINT_PAGER (pager)->priv;
+
+ if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR)
+ return NULL;
+
+ params = g_new0 (gchar *, params_max);
+
+ yelp_settings_params (&params, &params_i, &params_max);
+
+ if ((params_i + 10) >= params_max - 1) {
+ params_max += 20;
+ params = g_renew (gchar *, params, params_max);
+ }
+ params[params_i++] = "db.chunk.extension";
+ params[params_i++] = g_strdup ("\"\"");
+ params[params_i++] = "db.chunk.info_basename";
+ params[params_i++] = g_strdup ("\"index\"");
+ params[params_i++] = "db.chunk.max_depth";
+ params[params_i++] = g_strdup_printf ("0");
+ params[params_i++] = "yelp.javascript";
+ params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js");
+
+ params[params_i] = NULL;
+
+ return params;
+}
+
+static void
+db_print_pager_cancel (YelpPager *pager)
+{
+ YelpDBPrintPagerPriv *priv = YELP_DB_PRINT_PAGER (pager)->priv;
+
+ d (g_print ("db_print_pager_cancel\n"));
+
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID);
+
+ g_free (priv->root_id);
+ priv->root_id = NULL;
+
+ YELP_PAGER_CLASS (parent_class)->cancel (pager);
+}
+
+static const gchar *
+db_print_pager_resolve_frag (YelpPager *pager, const gchar *frag_id)
+{
+ YelpDBPrintPager *db_print_pager;
+
+ g_return_val_if_fail (pager != NULL, NULL);
+ g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), NULL);
+
+ db_print_pager = YELP_DB_PRINT_PAGER (pager);
+
+ return frag_id;
+}
+
diff --git a/src/yelp-db-print-pager.h b/src/yelp-db-print-pager.h
new file mode 100644
index 00000000..013e8af5
--- /dev/null
+++ b/src/yelp-db-print-pager.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 Shaun McCance <shaunm@gnome.org>
+ *
+ * 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 of the
+ * License, 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.
+ *
+ * Author: Shaun McCance <shaunm@gnome.org>
+ */
+
+#ifndef __YELP_DB_PRINT_PAGER_H__
+#define __YELP_DB_PRINT_PAGER_H__
+
+#include <glib-object.h>
+
+#include "yelp-pager.h"
+#include "yelp-xslt-pager.h"
+
+#define YELP_TYPE_DB_PRINT_PAGER (yelp_db_print_pager_get_type ())
+#define YELP_DB_PRINT_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPager))
+#define YELP_DB_PRINT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerClass))
+#define YELP_IS_DB_PRINT_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_DB_PRINT_PAGER))
+#define YELP_IS_DB_PRINT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_DB_PRINT_PAGER))
+#define YELP_DB_PRINT_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerClass))
+
+typedef struct _YelpDBPrintPager YelpDBPrintPager;
+typedef struct _YelpDBPrintPagerClass YelpDBPrintPagerClass;
+typedef struct _YelpDBPrintPagerPriv YelpDBPrintPagerPriv;
+
+struct _YelpDBPrintPager {
+ YelpXsltPager parent;
+
+ YelpDBPrintPagerPriv *priv;
+};
+
+struct _YelpDBPrintPagerClass {
+ YelpXsltPagerClass parent_class;
+};
+
+GType yelp_db_print_pager_get_type (void);
+YelpPager * yelp_db_print_pager_new (YelpDocInfo *doc_info);
+
+#endif /* __YELP_DB_PRINT_PAGER_H__ */
diff --git a/src/yelp-gecko-services.cpp b/src/yelp-gecko-services.cpp
new file mode 100644
index 00000000..a56c3a3f
--- /dev/null
+++ b/src/yelp-gecko-services.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2002 Philip Langdale
+ * Copyright (C) 2003-2004 Christian Persch
+ * Copyright (C) 2005 Juerg Billeter
+ * Copyright (C) 2005 Don Scorgie <DonScorgie@Blueyonder.co.uk>
+ *
+ * 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 <mozilla-config.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nsError.h"
+#undef MOZILLA_INTERNAL_API
+#include <nsEmbedString.h>
+#define MOZILLA_INTERNAL_API 1
+
+#include "yelp-gecko-services.h"
+
+#include <nsIPrintSettings.h>
+#include <nsCOMPtr.h>
+#include <nsIComponentRegistrar.h>
+#include <nsIInterfaceRequestorUtils.h>
+#include <nsIGenericFactory.h>
+#include <nsILocalFile.h>
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS3(GPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener, nsIPrintProgressParams)
+
+GPrintingPromptService::GPrintingPromptService()
+{
+ mPrintInfo = NULL;
+}
+
+GPrintingPromptService::~GPrintingPromptService()
+{
+ if (mPrintInfo != NULL)
+ {
+ yelp_print_info_free (mPrintInfo);
+ }
+}
+
+/* void showPrintDialog (in nsIDOMWindow parent, in nsIWebBrowserPrint webBrowserPrint, in nsIPrintSettings printSettings); */
+NS_IMETHODIMP GPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
+{
+ return NS_OK;
+
+}
+
+/* void showProgress (in nsIDOMWindow parent, in nsIWebBrowserPrint webBrowserPrint, in nsIPrintSettings printSettings, in nsIObserver openDialogObserver, in boolean isForPrinting, out nsIWebProgressListener webProgressListener, out nsIPrintProgressParams printProgressParams, out boolean notifyOnOpen); */
+NS_IMETHODIMP GPrintingPromptService::ShowProgress(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings, nsIObserver *openDialogObserver, PRBool isForPrinting, nsIWebProgressListener **webProgressListener, nsIPrintProgressParams **printProgressParams, PRBool *notifyOnOpen)
+{
+ return NS_OK;
+}
+
+/* void showPageSetup (in nsIDOMWindow parent, in nsIPrintSettings printSettings, in nsIObserver printObserver); */
+NS_IMETHODIMP GPrintingPromptService::ShowPageSetup(nsIDOMWindow *parent, nsIPrintSettings *printSettings,
+ nsIObserver *printObserver)
+{
+ return NS_OK;
+}
+
+/* void showPrinterProperties (in nsIDOMWindow parent, in wstring printerName, in nsIPrintSettings printSettings); */
+NS_IMETHODIMP GPrintingPromptService::ShowPrinterProperties(nsIDOMWindow *parent, const PRUnichar *printerName, nsIPrintSettings *printSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
+/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */
+NS_IMETHODIMP GPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
+{
+ return NS_OK;
+}
+
+/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
+NS_IMETHODIMP GPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
+{
+ return NS_OK;
+}
+
+/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
+NS_IMETHODIMP GPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
+NS_IMETHODIMP GPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
+NS_IMETHODIMP GPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute wstring docTitle; */
+NS_IMETHODIMP GPrintingPromptService::GetDocTitle(PRUnichar * *aDocTitle)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP GPrintingPromptService::SetDocTitle(const PRUnichar * aDocTitle)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute wstring docURL; */
+NS_IMETHODIMP GPrintingPromptService::GetDocURL(PRUnichar * *aDocURL)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP GPrintingPromptService::SetDocURL(const PRUnichar * aDocURL)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMPL_ISUPPORTS1(PrintListener, nsIWebProgressListener)
+
+ PrintListener::PrintListener (YelpPrintInfo *in, nsIWebBrowserPrint *p)
+{
+ info = in;
+ print = p;
+ cancel_happened = FALSE;
+ /*NULL*/
+
+}
+
+PrintListener::~PrintListener ()
+{
+ /*NULL*/
+}
+
+/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */
+NS_IMETHODIMP PrintListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
+NS_IMETHODIMP PrintListener::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
+{
+ yelp_print_update_progress (info,
+ (1.0 * aCurTotalProgress) / (aMaxTotalProgress * 1.0));
+
+ if (info->cancelled && !cancel_happened) {
+ /* This doesn't seem to actually cancel anything.
+ * therefore, the best course of action is to ignore it
+ * until we've finished printing to the file
+ * and then free it - Mozilla bug #253926
+ */
+ print->Cancel();
+ cancel_happened = TRUE;
+ }
+ if (aCurTotalProgress == 100 && aMaxTotalProgress == 100) /* 100% finished */
+ yelp_print_moz_finished (info);
+ return NS_OK;
+}
+
+/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
+NS_IMETHODIMP PrintListener::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
+NS_IMETHODIMP PrintListener::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
+NS_IMETHODIMP PrintListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(GPrintingPromptService)
+
+static const nsModuleComponentInfo sAppComps[] = {
+ {
+ G_PRINTINGPROMPTSERVICE_CLASSNAME,
+ G_PRINTINGPROMPTSERVICE_CID,
+ G_PRINTINGPROMPTSERVICE_CONTRACTID,
+ GPrintingPromptServiceConstructor
+ },
+};
+
+
+
+void
+yelp_register_printing ()
+{
+ gboolean ret = TRUE;
+ nsresult rv;
+ nsresult result;
+
+ nsCOMPtr<nsIComponentRegistrar> cr;
+
+ result = NS_GetComponentRegistrar(getter_AddRefs(cr));
+ nsCOMPtr<nsIComponentManager> cm;
+ NS_GetComponentManager (getter_AddRefs (cm));
+ nsCOMPtr<nsIGenericFactory> componentFactory;
+ rv = NS_NewGenericFactory(getter_AddRefs(componentFactory),
+ &(sAppComps[0]));
+
+ if (NS_FAILED(rv) || !componentFactory)
+ {
+ g_warning ("Failed to make a factory for %s\n", sAppComps[0].mDescription);
+
+ ret = FALSE;
+ }
+
+ rv = cr->RegisterFactory(sAppComps[0].mCID,
+ sAppComps[0].mDescription,
+ sAppComps[0].mContractID,
+ componentFactory);
+ if (NS_FAILED(rv))
+ {
+ g_warning ("Failed to register %s\n", sAppComps[0].mDescription);
+
+ ret = FALSE;
+ }
+
+}
diff --git a/src/yelp-gecko-services.h b/src/yelp-gecko-services.h
new file mode 100644
index 00000000..66262fe1
--- /dev/null
+++ b/src/yelp-gecko-services.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2000 Marco Pesenti Gritti
+ * Copyright (C) 2005 Don Scorgie <DonScorgie@Blueyonder.co.uk>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __YELP_GECKO_SERVICES_H
+#define __YELP_GECKO_SERVICES_H
+
+#include <nsIPrintingPromptService.h>
+#include <nsIWebProgressListener.h>
+#include <nsIPrintProgressParams.h>
+#include "yelp-print.h"
+
+#define G_PRINTINGPROMPTSERVICE_CID \
+ { /* dbf438d3-5f62-4978-a700-6fc39447477c */ \
+ 0xdbf438d3, 0x5f62, 0x4978, \
+ { 0xa7, 0x00, 0x6f, 0xc3, 0x94, 0x47, 0x47, 0x7c } }
+
+#define G_PRINTINGPROMPTSERVICE_CLASSNAME "Yelps Printing Prompt Service"
+#define G_PRINTINGPROMPTSERVICE_CONTRACTID "@mozilla.org/embedcomp/printingprompt-service;1"
+
+void yelp_register_printing ();
+
+/* Overwriting PrintPromptService makes the default mozilla print dialog
+ * not appear. We already have our print dialog shown
+ */
+class GPrintingPromptService : public nsIPrintingPromptService, nsIWebProgressListener, nsIPrintProgressParams
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_NSIPRINTPROGRESSPARAMS
+
+ GPrintingPromptService();
+ virtual ~GPrintingPromptService();
+
+protected:
+ YelpPrintInfo *mPrintInfo;
+};
+
+/* The PrintListener allows us to update the progress bars.
+ * Its not much help, but better than nothing
+ */
+class PrintListener : public nsIWebProgressListener
+{
+public:
+ PrintListener (YelpPrintInfo *in, nsIWebBrowserPrint *p);
+ virtual ~PrintListener ();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+ protected:
+ YelpPrintInfo *info;
+ nsIWebBrowserPrint *print;
+ gboolean cancel_happened;
+ gboolean called_finish;
+};
+
+
+
+
+
+#endif
diff --git a/src/yelp-html.cpp b/src/yelp-html.cpp
index f1513ab8..50ec8416 100644
--- a/src/yelp-html.cpp
+++ b/src/yelp-html.cpp
@@ -31,9 +31,12 @@
#include "yelp-marshal.h"
#include "yelp-gecko-utils.h"
#include "yelp-settings.h"
+#include "yelp-gecko-services.h"
#include "Yelper.h"
+#include <libgnome/gnome-init.h>
+
#ifdef GNOME_ENABLE_DEBUG
#define d(x) x
#else
@@ -130,7 +133,6 @@ html_init (YelpHtml *html)
priv->anchor = NULL;
priv->yelper = new Yelper (GTK_MOZ_EMBED (html));
-
klass = YELP_HTML_GET_CLASS (html);
if (!klass->font_handler) {
klass->font_handler =
@@ -153,6 +155,7 @@ html_init (YelpHtml *html)
NULL);
html_set_a11y ();
}
+ yelp_register_printing ();
}
static void
@@ -384,6 +387,24 @@ yelp_html_select_all (YelpHtml *html)
html->priv->yelper->DoCommand ("cmd_selectAll");
}
+void
+yelp_html_print (YelpHtml *html, YelpPrintInfo *info, gboolean preview, gint *npages)
+{
+ html->priv->yelper->Print (info, preview, npages);
+}
+
+void
+yelp_html_preview_navigate (YelpHtml *html, gint page_no)
+{
+ html->priv->yelper->PrintPreviewNavigate (page_no);
+}
+
+void
+yelp_html_preview_end (YelpHtml *html)
+{
+ html->priv->yelper->PrintPreviewEnd ();
+}
+
static void
html_set_fonts (void)
{
@@ -421,3 +442,16 @@ html_set_a11y (void)
caret = yelp_settings_get_caret ();
yelp_gecko_set_caret (caret);
}
+
+void
+yelp_html_initialize (void)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+ initialized = TRUE;
+
+ gtk_moz_embed_set_comp_path (MOZILLA_HOME);
+
+}
diff --git a/src/yelp-html.h b/src/yelp-html.h
index 66f1fae4..cd125bac 100644
--- a/src/yelp-html.h
+++ b/src/yelp-html.h
@@ -28,6 +28,8 @@
#include <gtk/gtkmarshal.h>
#include <gtkmozembed.h>
+#include "yelp-print.h"
+
G_BEGIN_DECLS
#define YELP_TYPE_HTML (yelp_html_get_type ())
@@ -98,6 +100,15 @@ void yelp_html_copy_selection (YelpHtml *html);
void yelp_html_select_all (YelpHtml *html);
+void yelp_html_print (YelpHtml *html,
+ YelpPrintInfo *info,
+ gboolean preview,
+ gint *npages);
+void yelp_html_preview_end (YelpHtml *html);
+void yelp_html_preview_navigate (YelpHtml *html,
+ gint page_no);
+void yelp_html_initialize (void);
+
G_END_DECLS
#endif /* __YELP_HTML_H__ */
diff --git a/src/yelp-main.c b/src/yelp-main.c
index 5ab047ff..225e2180 100644
--- a/src/yelp-main.c
+++ b/src/yelp-main.c
@@ -37,11 +37,11 @@
#include <libgnomeui/gnome-client.h>
#include <string.h>
#include <stdlib.h>
-#include <gtkmozembed.h>
#include "GNOME_Yelp.h"
#include "yelp-window.h"
#include "yelp-base.h"
+#include "yelp-html.h"
#define YELP_FACTORY_OAFIID "OAFIID:GNOME_Yelp_Factory"
@@ -333,8 +333,8 @@ main (int argc, char **argv)
gnome_vfs_init ();
- gtk_moz_embed_set_comp_path (MOZILLA_HOME);
-
+ yelp_html_initialize ();
+
/* Commandline parsing is done here */
g_object_get (G_OBJECT (program),
GNOME_PARAM_POPT_CONTEXT, &poptCon,
@@ -366,6 +366,7 @@ main (int argc, char **argv)
BonoboGenericFactory *factory;
char *registration_id;
+
registration_id = bonobo_activation_make_registration_id (
YELP_FACTORY_OAFIID,
gdk_display_get_name (gdk_display_get_default ()));
diff --git a/src/yelp-print.c b/src/yelp-print.c
new file mode 100644
index 00000000..2dad03cb
--- /dev/null
+++ b/src/yelp-print.c
@@ -0,0 +1,743 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2002 Jorn Baayen
+ * Copyright (C) 2003, 2004 Christian Persch
+ * Copyright (C) 2005 Juerg Billeter
+ * Copyright (C) 2005 Don Scorgie <DonScorgie@Blueyonder.co.uk>
+ *
+ * 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 of the
+ * License, 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 <unistd.h>
+#include <sys/stat.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <string.h>
+#include "yelp-print.h"
+#include "yelp-html.h"
+#include "yelp-utils.h"
+
+static GnomePrintConfig * yelp_print_load_config_from_file ( void );
+static void yelp_print_save_config_to_file (GnomePrintConfig *config);
+static void cancel_print_cb (GtkDialog *dialog,
+ gint arg1,
+ YelpPrintInfo *info);
+static void parent_destroyed_cb (GtkWindow *window,
+ YelpPrintInfo *info);
+static gboolean print_jobs_run ( void );
+void print_present_config_dialog (YelpPrintInfo *info);
+static YelpPrintInfo * yelp_print_get_print_info ( void );
+GtkWidget * yelp_print_dialog_new (YelpPrintInfo *info);
+void yelp_print_info_free (YelpPrintInfo *info);
+gboolean yelp_print_verify_postscript (GnomePrintDialog *print_dialog);
+void yelp_print_present_status_dialog (YelpWindow *window,
+ YelpPrintInfo *info);
+void yelp_print_dialog_response_cb (GtkDialog *dialog,
+ int response,
+ YelpPrintInfo *info);
+static void print_construct_range_page (GnomePrintDialog *gpd,
+ gint flags,
+ const guchar *currentlabel,
+ const guchar *rangelabel);
+gboolean yelp_print_preview (YelpPrintInfo *info);
+
+gboolean print_preview_finished_cb (GtkWindow *win,
+ GdkEvent *ev,
+ YelpPrintInfo *info);
+void preview_go_first (GtkToolButton *b,
+ YelpPrintInfo *info);
+void preview_go_back (GtkToolButton *b,
+ YelpPrintInfo *info);
+void preview_go_forward (GtkToolButton *b,
+ YelpPrintInfo *info);
+void preview_go_last (GtkToolButton *b,
+ YelpPrintInfo *info);
+void preview_close (GtkToolButton *b,
+ YelpPrintInfo *info);
+gboolean print_free_idle_cb (YelpPrintInfo *info);
+
+static GSList * current_jobs = NULL;
+
+static gboolean currently_running = FALSE;
+
+void
+yelp_print_run (YelpWindow *window, gpointer html, gpointer fake_win,
+ gpointer content_box)
+{
+ YelpPrintInfo *info;
+
+ info = yelp_print_get_print_info ();
+ info->owner = window;
+ info->html_frame = html;
+ info->fake_win = fake_win;
+ info->content_box = content_box;
+
+ print_present_config_dialog (info);
+
+}
+
+void
+print_present_config_dialog (YelpPrintInfo *info)
+{
+ GtkWidget *dialog;
+ int ret;
+
+ dialog = yelp_print_dialog_new (info);
+ while (TRUE) {
+ ret = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (ret != GNOME_PRINT_DIALOG_RESPONSE_PRINT)
+ break;
+ if (yelp_print_verify_postscript (GNOME_PRINT_DIALOG (dialog)))
+ break;
+ }
+ gtk_widget_destroy (dialog);
+ if (ret == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW) {
+ g_idle_add ((GSourceFunc) yelp_print_preview, info);
+ return;
+ }
+ if (ret != GNOME_PRINT_DIALOG_RESPONSE_PRINT) {
+ yelp_print_info_free (info);
+ return;
+ }
+ yelp_print_present_status_dialog (info->owner, info);
+ info->cancel_print_id = g_signal_connect (info->owner, "destroy",
+ G_CALLBACK (parent_destroyed_cb),
+ info);
+
+ current_jobs = g_slist_append (current_jobs, info);
+
+ if (!currently_running) {
+ g_idle_add ((GSourceFunc) print_jobs_run,
+ NULL);
+ currently_running = TRUE;
+ }
+
+}
+
+static gboolean
+print_jobs_run ()
+{
+ YelpPrintInfo * info = current_jobs->data;
+ info->started = TRUE;
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (info->dialog),
+ _("Preparing to print"));
+
+ yelp_html_print (info->html_frame, info, FALSE, NULL);
+
+ return FALSE;
+}
+
+static GnomePrintConfig *
+yelp_print_load_config_from_file ()
+{
+ GnomePrintConfig *config = NULL;
+ gchar *filename, *contents = NULL;
+
+ filename = g_build_filename (yelp_dot_dir(), "yelp-printing.xml", NULL);
+ if (g_file_get_contents (filename, &contents, NULL, NULL)) {
+ config = gnome_print_config_from_string (contents, 0);
+ g_free (contents);
+ } else {
+ config = gnome_print_config_default ();
+
+ }
+
+ g_free (filename);
+
+ return config;
+}
+
+static void
+yelp_print_save_config_to_file (GnomePrintConfig *config)
+{
+ gchar *filename, *str;
+
+ str = gnome_print_config_to_string (config, 0);
+ if (str == NULL) return;
+
+ filename = g_build_filename ( yelp_dot_dir (), "yelp-printing.xml", NULL);
+ g_file_set_contents (filename, str, -1, NULL);
+
+ g_free (str);
+ g_free (filename);
+
+}
+
+void
+yelp_print_info_free (YelpPrintInfo *info)
+{
+ if (info) {
+ g_object_unref (info->config);
+ if (info->tempfile) {
+ g_unlink (info->tempfile);
+ g_free (info->tempfile);
+ }
+ g_free (info->header_left_string);
+ g_free (info->header_center_string);
+ g_free (info->header_right_string);
+ g_free (info->footer_left_string);
+ g_free (info->footer_center_string);
+ g_free (info->footer_right_string);
+ if (info->dialog != NULL) {
+ gtk_widget_destroy (info->progress);
+ gtk_widget_destroy (info->dialog);
+ }
+ if (info->fake_win)
+ gtk_widget_destroy (info->fake_win);
+ if (info->cancel_print_id) {
+ g_signal_handler_disconnect (info->owner, info->cancel_print_id);
+ }
+ g_free (info);
+ }
+
+}
+
+YelpPrintInfo *
+yelp_print_get_print_info ()
+{
+ YelpPrintInfo *info;
+
+ info = g_new0 (YelpPrintInfo, 1);
+
+ info->config = yelp_print_load_config_from_file ();
+
+ info->range = GNOME_PRINT_RANGE_ALL;
+ info->from_page = 1;
+ info->to_page = 1;
+
+ info->frame_type = 0;
+ info->print_color = FALSE;
+
+ info->cancelled = FALSE;
+ info->moz_finished = FALSE;
+
+ info->dialog = NULL;
+
+ info->header_left_string = g_strdup ("&T");
+ info->header_center_string = g_strdup ("");
+ info->header_right_string = g_strdup ("");
+ info->footer_left_string = g_strdup ("");
+ info->footer_center_string = g_strdup ("&PT");
+ info->footer_right_string = g_strdup ("");
+
+
+ return info;
+}
+
+void
+yelp_print_dialog_response_cb (GtkDialog *dialog,
+ int response,
+ YelpPrintInfo *info)
+{
+ if (response == GNOME_PRINT_DIALOG_RESPONSE_PRINT ||
+ response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW) {
+ info->range = gnome_print_dialog_get_range_page (GNOME_PRINT_DIALOG (dialog),
+ &info->from_page,
+ &info->to_page);
+ yelp_print_save_config_to_file (info->config);
+ }
+
+}
+
+
+GtkWidget *
+yelp_print_dialog_new (YelpPrintInfo *info)
+{
+ GtkWidget *dialog;
+
+ dialog= g_object_new (GNOME_TYPE_PRINT_DIALOG, "print_config",
+ info->config, NULL);
+
+ gnome_print_dialog_construct (GNOME_PRINT_DIALOG (dialog),
+ (const guchar *) "Print",
+ GNOME_PRINT_DIALOG_RANGE |
+ GNOME_PRINT_DIALOG_COPIES);
+
+ print_construct_range_page (GNOME_PRINT_DIALOG (dialog),
+ GNOME_PRINT_RANGE_ALL |
+ GNOME_PRINT_RANGE_RANGE |
+ GNOME_PRINT_RANGE_SELECTION,
+ NULL, (const guchar *) _("Pages"));
+
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (yelp_print_dialog_response_cb), info);
+
+ return dialog;
+
+}
+
+static gboolean
+using_pdf_printer (GnomePrintConfig *config)
+{
+ const gchar *driver;
+
+ driver = (gchar *) gnome_print_config_get (config,
+ (const guchar *)
+ "Settings.Engine.Backend.Driver");
+
+ if (driver) {
+ if (!strcmp ((const gchar *)driver, "gnome-print-pdf"))
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return FALSE;
+
+}
+
+static gboolean
+using_postscript_printer (GnomePrintConfig *config)
+{
+ const guchar *driver;
+ const guchar *transport;
+
+ 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") == 0)
+ return TRUE;
+ else
+ return FALSE;
+
+ } else if (transport) {
+ if (strcmp ((const gchar *) transport, "CUPS") == 0)
+ return TRUE;
+ else if (strcmp ((const gchar *) transport, "LPD") == 0)
+ return TRUE;
+
+ }
+ return FALSE;
+
+}
+
+gboolean
+yelp_print_verify_postscript (GnomePrintDialog *print_dialog)
+{
+ GnomePrintConfig *config;
+ GtkWidget *dialog;
+
+ config = gnome_print_dialog_get_config (print_dialog);
+
+ if (using_postscript_printer (config))
+ return TRUE;
+
+ if (using_pdf_printer (config)) {
+ dialog = gtk_message_dialog_new ( GTK_WINDOW (print_dialog),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Generating PDF is not "
+ "currently supported"));
+
+ } else {
+ dialog = gtk_message_dialog_new ( GTK_WINDOW (print_dialog),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Printing is not supported on this "
+ "printer"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("You were trying to print "
+ "to a printer using the \""
+ "%s\" driver. This program "
+ "requires a PostScript "
+ "printer driver."),
+ gnome_print_config_get (config,
+ (guchar *) "Settings.Engine.Backend.Driver"));
+
+ }
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ return FALSE;
+}
+
+static gboolean
+print_idle_cb (YelpPrintInfo *info)
+{
+ GnomePrintJob *job;
+ gint result;
+
+ if (g_file_test (info->tempfile, G_FILE_TEST_EXISTS) == FALSE) return FALSE;
+
+ /* FIXME: is this actually necessary? libc docs say all streams
+ * are flushed when reading from any stream.
+ */
+ fflush(NULL);
+
+ job = gnome_print_job_new (info->config);
+
+ gnome_print_job_set_file (job, info->tempfile);
+ result = gnome_print_job_print (job);
+ g_object_unref (job);
+
+ if (result != GNOME_PRINT_OK) {
+ /*There was an error printing. Panic.*/
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ _("An error "
+ "occured while printing")
+ );
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("It was not possible to "
+ "print your document"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (dialog);
+ gtk_widget_destroy (dialog);
+ }
+
+ yelp_print_info_free (info);
+
+ if (g_slist_length (current_jobs) > 0)
+ g_idle_add ((GSourceFunc) print_jobs_run, NULL);
+ else
+ currently_running = FALSE;
+
+ return FALSE;
+
+}
+
+static void
+parent_destroyed_cb (GtkWindow *window, YelpPrintInfo *info)
+{
+ current_jobs = g_slist_remove (current_jobs, info);
+ if (info->started) {
+ info->cancelled = TRUE;
+ if (info->moz_finished) {
+ if (info->print_idle_id)
+ g_source_remove (info->print_idle_id);
+ yelp_print_info_free (info);
+ }
+ } else {
+ yelp_print_info_free (info);
+ }
+}
+
+static void
+cancel_print_cb (GtkDialog *dialog, gint arg1, YelpPrintInfo *info)
+{
+ gtk_widget_hide (info->dialog);
+ if (info->started) {
+ info->cancelled = TRUE;
+ if (info->moz_finished) {
+ if (info->print_idle_id)
+ g_source_remove (info->print_idle_id);
+ yelp_print_info_free (info);
+ }
+ } else {
+ current_jobs = g_slist_remove (current_jobs, info);
+ yelp_print_info_free (info);
+ }
+}
+
+void
+yelp_print_moz_finished (YelpPrintInfo *info)
+{
+ info->moz_finished = TRUE;
+
+ current_jobs = g_slist_remove (current_jobs, info);
+
+ if (!info->cancelled) {
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (info->dialog),
+ _("Printing"));
+
+ info->print_idle_id = g_idle_add ((GSourceFunc) print_idle_cb,
+ info);
+
+ } else {
+ if (g_slist_length (current_jobs) == 0) {
+ currently_running = FALSE;
+ } else {
+ g_idle_add ((GSourceFunc) print_jobs_run,
+ NULL);
+ }
+ g_idle_add ((GSourceFunc) print_free_idle_cb, info);
+ }
+
+}
+
+void
+yelp_print_present_status_dialog (YelpWindow *window, YelpPrintInfo *info)
+{
+ if (info->dialog != NULL)
+ return;
+
+ info->dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CANCEL,
+ _("<b>Printing</b>"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (info->dialog),
+ _("Waiting to print"));
+ info->progress = gtk_progress_bar_new ();
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(info->dialog)->vbox),
+ info->progress);
+
+ gtk_widget_show (info->progress);
+
+ g_signal_connect (info->dialog, "response",
+ G_CALLBACK (cancel_print_cb),
+ (gpointer) info);
+
+ gtk_window_present (GTK_WINDOW (info->dialog));
+}
+
+void
+yelp_print_cancel (YelpPrintInfo *info)
+{
+ cancel_print_cb (NULL, 0, info);
+}
+
+void
+yelp_print_update_progress (YelpPrintInfo *info, gdouble percentage)
+{
+ /* This is horribly inefficient, but since we're waiting for
+ * mozilla to do its thing, might as well waste a few cycles
+ */
+ YelpPrintInfo * temp;
+ GSList *jobs = current_jobs;
+ while (g_slist_length (jobs) != 0) {
+ temp = jobs->data;
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (temp->progress));
+ jobs = g_slist_next(jobs);
+ }
+ jobs = g_slist_find (current_jobs, info);
+ temp = jobs->data;
+ if (percentage > 1.0)
+ percentage = 1.0;
+ else if (percentage <0.0)
+ percentage = 0.0;
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (temp->progress),
+ percentage);
+
+}
+
+/* Ranges page when we don't actually know the length of the
+ * document
+ */
+static void
+print_construct_range_page (GnomePrintDialog *gpd, gint flags,
+ const guchar *currentlabel,
+ const guchar *rangelabel)
+{
+ GtkWidget *hbox;
+
+ hbox = NULL;
+
+ if (flags & GNOME_PRINT_RANGE_RANGE) {
+ GtkWidget *l, *sb;
+ GtkObject *a;
+ AtkObject *atko;
+
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_widget_show (hbox);
+
+ l = gtk_label_new_with_mnemonic (_("_From:"));
+ gtk_widget_show (l);
+ gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0);
+
+ a = gtk_adjustment_new (1, 1, 9999, 1, 10, 10);
+ g_object_set_data (G_OBJECT (hbox), "from", a);
+ sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1, 0.0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (sb), TRUE);
+ gtk_widget_show (sb);
+ gtk_box_pack_start (GTK_BOX (hbox), sb, FALSE, FALSE, 0);
+ gtk_label_set_mnemonic_widget ((GtkLabel *) l, sb);
+
+ atko = gtk_widget_get_accessible (sb);
+ atk_object_set_description (atko, _("Sets the start of the range of pages to be printed"));
+
+ l = gtk_label_new_with_mnemonic (_("_To:"));
+ gtk_widget_show (l);
+ gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0);
+
+ a = gtk_adjustment_new (1, 1, 9999, 1, 10, 10);
+ g_object_set_data (G_OBJECT (hbox), "to", a);
+ sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1, 0.0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (sb), TRUE);
+ gtk_widget_show (sb);
+ gtk_box_pack_start (GTK_BOX (hbox), sb, FALSE, FALSE, 0);
+ gtk_label_set_mnemonic_widget ((GtkLabel *) l, sb);
+
+ atko = gtk_widget_get_accessible (sb);
+ atk_object_set_description (atko, _("Sets the end of the range of pages to be printed"));
+ }
+
+ gnome_print_dialog_construct_range_any (gpd, flags, hbox, currentlabel, rangelabel);
+}
+
+gboolean
+yelp_print_preview (YelpPrintInfo *info)
+{
+ gint width, height;
+ /* Add some funky nav widgets to the fake_win since we're gonna
+ * have to actually show it now :(
+ */
+ if (!info->previewed) {
+ info->previewed = TRUE;
+ GtkWidget *box = gtk_toolbar_new ();
+
+ gtk_box_pack_start (GTK_BOX (info->content_box), box, FALSE, FALSE, 0);
+ info->GoFirst = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GOTO_FIRST));
+ gtk_container_add (GTK_CONTAINER (box), info->GoFirst);
+ g_signal_connect (info->GoFirst, "clicked",
+ G_CALLBACK (preview_go_first),
+ info);
+ gtk_widget_show (info->GoFirst);
+
+ info->GoBack = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK));
+ gtk_container_add (GTK_CONTAINER (box), info->GoBack);
+ g_signal_connect (info->GoBack, "clicked",
+ G_CALLBACK (preview_go_back),
+ info);
+ gtk_widget_show (info->GoBack);
+
+ info->GoForward = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD));
+ gtk_container_add (GTK_CONTAINER (box), info->GoForward);
+ g_signal_connect (info->GoForward, "clicked",
+ G_CALLBACK (preview_go_forward),
+ info);
+ gtk_widget_show (info->GoForward);
+
+ info->GoLast = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_GOTO_LAST));
+ gtk_container_add (GTK_CONTAINER (box), info->GoLast);
+ g_signal_connect (info->GoLast, "clicked",
+ G_CALLBACK (preview_go_last),
+ info);
+ gtk_widget_show (info->GoLast);
+
+ info->Close = GTK_WIDGET (gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE));
+ gtk_container_add (GTK_CONTAINER (box), info->Close);
+ g_signal_connect (info->Close, "clicked",
+ G_CALLBACK (preview_close),
+ info);
+ gtk_widget_show (info->Close);
+
+ gtk_widget_show (box);
+ }
+ gtk_window_set_modal (GTK_WINDOW (info->fake_win), TRUE);
+ gtk_widget_set_sensitive (info->GoFirst, FALSE);
+ gtk_widget_set_sensitive (info->GoBack, FALSE);
+ info->currentpage = 1;
+ yelp_html_print (info->html_frame, info, TRUE, &(info->npages));
+
+ if (info->npages == 1) { /*Desensitise all buttons */
+ gtk_widget_set_sensitive (info->GoForward, FALSE);
+ gtk_widget_set_sensitive (info->GoLast, FALSE);
+ }
+ g_signal_connect (info->fake_win, "delete-event",
+ G_CALLBACK (print_preview_finished_cb),
+ info);
+
+ /* Set the preview window to the same size as the real window */
+ gtk_window_get_size (GTK_WINDOW (info->owner), &width, &height);
+ gtk_window_resize (GTK_WINDOW (info->fake_win), width, height);
+
+ gtk_widget_show (GTK_WIDGET (info->fake_win));
+
+ return FALSE;
+}
+
+gboolean
+print_preview_finished_cb (GtkWindow *win, GdkEvent *ev, YelpPrintInfo *info)
+{
+ gtk_widget_hide (GTK_WIDGET (info->fake_win));
+ yelp_html_preview_end (info->html_frame);
+ print_present_config_dialog (info);
+ return TRUE;
+}
+
+void
+preview_go_first (GtkToolButton *b, YelpPrintInfo *info)
+{
+ info->currentpage = 1;
+ yelp_html_preview_navigate (info->html_frame, info->currentpage);
+
+ /* Reset sensitives */
+ gtk_widget_set_sensitive (info->GoBack, FALSE);
+ gtk_widget_set_sensitive (info->GoFirst, FALSE);
+ gtk_widget_set_sensitive (info->GoForward, TRUE);
+ gtk_widget_set_sensitive (info->GoLast, TRUE);
+}
+
+void
+preview_go_back (GtkToolButton *b, YelpPrintInfo *info)
+{
+ info->currentpage--;
+ yelp_html_preview_navigate (info->html_frame, info->currentpage);
+
+ /* Reset sensitives */
+ gtk_widget_set_sensitive (info->GoForward, TRUE);
+ gtk_widget_set_sensitive (info->GoLast, TRUE);
+
+ if (info->currentpage == 1) {
+ gtk_widget_set_sensitive (info->GoBack, FALSE);
+ gtk_widget_set_sensitive (info->GoFirst, FALSE);
+ }
+}
+
+void
+preview_go_forward (GtkToolButton *b, YelpPrintInfo *info)
+{
+ info->currentpage++;
+ yelp_html_preview_navigate (info->html_frame, info->currentpage);
+ /* Reset sensitives */
+ gtk_widget_set_sensitive (info->GoBack, TRUE);
+ gtk_widget_set_sensitive (info->GoFirst, TRUE);
+
+ if (info->currentpage == info->npages) {
+ gtk_widget_set_sensitive (info->GoForward, FALSE);
+ gtk_widget_set_sensitive (info->GoLast, FALSE);
+ }
+}
+
+void
+preview_go_last (GtkToolButton *b, YelpPrintInfo *info)
+{
+ info->currentpage=info->npages;
+ yelp_html_preview_navigate (info->html_frame, info->currentpage);
+
+ /* Reset sensitives */
+ gtk_widget_set_sensitive (info->GoBack, TRUE);
+ gtk_widget_set_sensitive (info->GoFirst, TRUE);
+ gtk_widget_set_sensitive (info->GoForward, FALSE);
+ gtk_widget_set_sensitive (info->GoLast, FALSE);
+
+}
+
+void
+preview_close (GtkToolButton *b, YelpPrintInfo *info)
+{
+ print_preview_finished_cb (NULL, NULL, info);
+}
+
+gboolean
+print_free_idle_cb (YelpPrintInfo *info)
+{
+ yelp_print_info_free (info);
+ return FALSE;
+}
diff --git a/src/yelp-print.h b/src/yelp-print.h
new file mode 100644
index 00000000..be3a293e
--- /dev/null
+++ b/src/yelp-print.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2005 Don Scorgie <DonScorgie@Blueyonder.co.uk>
+ *
+ * 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 of the
+ * License, 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.
+ *
+ * Author: Don Scorgie <DonScorgie@Blueyonder.co.uk>
+ */
+
+#ifndef YELP_PRINT_H
+#define YELP_PRINT_H
+
+#include <glib.h>
+#define GNOME_PRINT_UNSTABLE_API
+#include <libgnomeprint/gnome-print-config.h>
+#include <libgnomeprintui/gnome-print-dialog.h>
+
+#include "yelp-window.h"
+
+G_BEGIN_DECLS
+
+
+typedef struct _YelpPrintInfo
+{
+ GnomePrintConfig *config;
+
+ char *tempfile;
+ guint print_idle_id;
+ guint cancel_print_id;
+
+ GnomePrintDialogRangeFlags range;
+ int from_page;
+ int to_page;
+ int frame_type;
+ gboolean print_color;
+ gboolean cancelled;
+ gboolean moz_finished;
+ gboolean started;
+ gboolean previewed;
+
+ char *header_left_string;
+ char *header_center_string;
+ char *header_right_string;
+ char *footer_left_string;
+ char *footer_center_string;
+ char *footer_right_string;
+ YelpWindow *owner;
+ GtkWidget *dialog;
+ gpointer html_frame;
+ GtkWidget *progress;
+ GtkWidget *fake_win;
+ GtkWidget *content_box;
+
+ /* Preview buttons */
+ GtkWidget *GoBack;
+ GtkWidget *GoForward;
+ GtkWidget *GoFirst;
+ GtkWidget *GoLast;
+ GtkWidget *Close;
+ gint npages;
+ gint currentpage;
+
+
+} YelpPrintInfo;
+
+void yelp_print_run (YelpWindow *window,
+ gpointer html,
+ gpointer fake_win,
+ gpointer content_box);
+void yelp_print_moz_finished (YelpPrintInfo *info);
+void yelp_print_cancel (YelpPrintInfo *info);
+void yelp_print_info_free (YelpPrintInfo *info);
+void yelp_print_update_progress (YelpPrintInfo *info,
+ gdouble percentage);
+G_END_DECLS
+
+#endif
diff --git a/src/yelp-window.c b/src/yelp-window.c
index 97b3a4cd..00004120 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -42,12 +42,14 @@
#include "yelp-bookmarks.h"
#include "yelp-db-pager.h"
+#include "yelp-db-print-pager.h"
#include "yelp-error.h"
#include "yelp-html.h"
#include "yelp-pager.h"
#include "yelp-settings.h"
#include "yelp-toc-pager.h"
#include "yelp-window.h"
+#include "yelp-print.h"
#ifdef ENABLE_MAN
#include "yelp-man-pager.h"
@@ -160,6 +162,8 @@ static void window_add_widget (GtkUIManager *ui_manager,
GtkWidget *vbox);
static void window_new_window_cb (GtkAction *action, YelpWindow *window);
static void window_about_document_cb (GtkAction *action, YelpWindow *window);
+static void window_print_document_cb (GtkAction *action, YelpWindow *window);
+static void window_print_page_cb (GtkAction *action, YelpWindow *window);
static void window_open_location_cb (GtkAction *action, YelpWindow *window);
static void window_close_window_cb (GtkAction *action, YelpWindow *window);
static void window_copy_cb (GtkAction *action, YelpWindow *window);
@@ -309,6 +313,16 @@ static const GtkActionEntry entries[] = {
"<Control>N",
NULL,
G_CALLBACK (window_new_window_cb) },
+ { "PrintDocument", NULL,
+ N_("Print This Document"),
+ NULL,
+ NULL,
+ G_CALLBACK (window_print_document_cb) },
+ { "PrintPage", NULL,
+ N_("Print This Page"),
+ NULL,
+ NULL,
+ G_CALLBACK (window_print_page_cb) },
{ "AboutDocument", NULL,
N_("About This Document"),
NULL,
@@ -723,6 +737,7 @@ yelp_window_load (YelpWindow *window, const gchar *uri)
YelpWindowPriv *priv;
YelpDocInfo *doc_info;
gchar *frag_id;
+ GtkAction *action;
g_return_if_fail (YELP_IS_WINDOW (window));
@@ -770,6 +785,11 @@ yelp_window_load (YelpWindow *window, const gchar *uri)
if (priv->current_frag)
g_free (priv->current_frag);
+ action = gtk_action_group_get_action (priv->action_group,
+ "PrintDocument");
+ g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
+
+
priv->current_doc = yelp_doc_info_ref (doc_info);
priv->current_frag = g_strdup (frag_id);
@@ -801,6 +821,7 @@ window_do_load (YelpWindow *window,
YelpDocInfo *doc_info,
gchar *frag_id)
{
+ GtkAction *action;
YelpWindowPriv *priv;
GError *error = NULL;
gboolean handled = FALSE;
@@ -813,6 +834,13 @@ window_do_load (YelpWindow *window,
priv = window->priv;
+ action = gtk_action_group_get_action (priv->action_group,
+ "PrintDocument");
+ g_object_set (G_OBJECT (action),
+ "sensitive",
+ FALSE,
+ NULL);
+
switch (yelp_doc_info_get_type (doc_info)) {
case YELP_DOC_TYPE_MAN:
#ifdef ENABLE_MAN
@@ -835,6 +863,10 @@ window_do_load (YelpWindow *window,
#endif
case YELP_DOC_TYPE_DOCBOOK_XML:
+ g_object_set (G_OBJECT (action),
+ "sensitive",
+ TRUE,
+ NULL);
case YELP_DOC_TYPE_TOC:
handled = window_do_load_pager (window, doc_info, frag_id);
break;
@@ -1017,6 +1049,11 @@ window_populate (YelpWindow *window)
action = gtk_action_group_get_action (priv->action_group, "GoForward");
if (action)
g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
+
+ action = gtk_action_group_get_action (priv->action_group,
+ "PrintDocument");
+ g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
+
priv->popup = gtk_ui_manager_get_widget(priv->ui_manager, "ui/main_popup");
priv->maillink = gtk_ui_manager_get_widget(priv->ui_manager, "ui/mail_popup");
priv->merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
@@ -1935,6 +1972,254 @@ window_new_window_cb (GtkAction *action, YelpWindow *window)
g_signal_emit (window, signals[NEW_WINDOW_REQUESTED], 0, NULL);
}
+typedef struct {
+ gulong page_handler;
+ gulong error_handler;
+ gulong cancel_handler;
+ gulong finish_handler;
+ YelpPager *pager;
+ YelpWindow *window;
+} PrintStruct;
+
+static void
+print_disconnect (PrintStruct *data)
+{
+ d(g_print ("print disconnect\n"));
+ if (data->page_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->page_handler);
+ data->page_handler = 0;
+ }
+ if (data->error_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->error_handler);
+ data->error_handler = 0;
+ }
+ if (data->cancel_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->cancel_handler);
+ data->cancel_handler = 0;
+ }
+ if (data->finish_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->finish_handler);
+ data->finish_handler = 0;
+ }
+ g_free (data);
+}
+
+static void
+print_pager_page_cb (YelpPager *pager,
+ gchar *page_id,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+ YelpPage *page;
+ d (g_print ("print_pager_page_cb\n"));
+ d (g_print (" page_id=\"%s\"\n", page_id));
+
+ page = (YelpPage *) yelp_pager_get_page (pager, page_id);
+
+ if (page) {
+ YelpHtml *html;
+ GtkWidget *gtk_window;
+ int length, offset;
+ char *uri;
+ GtkWidget *vbox = gtk_vbox_new (FALSE, FALSE);
+ d(g_print (page->contents));
+
+ gtk_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ html = yelp_html_new ();
+
+ gtk_container_add (GTK_CONTAINER (gtk_window), GTK_WIDGET (vbox));
+ gtk_box_pack_end (GTK_BOX (vbox), GTK_WIDGET (html), TRUE, TRUE, 0);
+
+ gtk_widget_show (gtk_window);
+ gtk_widget_show (GTK_WIDGET (html));
+ gtk_widget_show (vbox);
+ gtk_widget_hide (gtk_window);
+ uri = yelp_doc_info_get_uri (yelp_pager_get_doc_info (pager),
+ page_id,
+ YELP_URI_TYPE_FILE);
+
+ d (g_print (" uri = %s\n", uri));
+
+ yelp_html_set_base_uri (html, uri);
+ g_free (uri);
+
+ yelp_html_open_stream (html, "application/xhtml+xml");
+ for (length = strlen (page->contents), offset = 0; length > 0; length -= BUFFER_SIZE, offset += BUFFER_SIZE) {
+ d(g_print ("data: %.*s\n", MIN (length, BUFFER_SIZE), page->contents + offset));
+ yelp_html_write (html, page->contents + offset, MIN (length, BUFFER_SIZE));
+ }
+ yelp_html_close (html);
+
+ yelp_print_run (data->window, html, gtk_window, vbox);
+
+ print_disconnect (data);
+
+ }
+}
+
+static void
+print_pager_error_cb (YelpPager *pager,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+ /* GError *error = yelp_pager_get_error (pager);*/
+
+ d (g_print ("print_pager_error_cb\n"));
+
+ print_disconnect (data);
+}
+
+static void
+print_pager_cancel_cb (YelpPager *pager,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+ d (g_print ("print_pager_cancel_cb\n"));
+
+ print_disconnect (data);
+}
+
+static void
+print_pager_finish_cb (YelpPager *pager,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+
+ d (g_print ("print_pager_finish_cb\n"));
+
+ print_disconnect (data);
+}
+
+static void
+window_print_document_cb (GtkAction *action, YelpWindow *window)
+{
+ PrintStruct *data;
+ YelpPager *pager;
+
+ if (!window->priv->current_doc)
+ return;
+
+ pager = yelp_db_print_pager_new (window->priv->current_doc);
+
+ if (!pager) {
+ return;
+ }
+
+ data = g_new0 (PrintStruct, 1);
+ data->pager = pager;
+ data->window = window;
+
+ data->page_handler =
+ g_signal_connect (data->pager,
+ "page",
+ G_CALLBACK (print_pager_page_cb),
+ data);
+ data->error_handler =
+ g_signal_connect (data->pager,
+ "error",
+ G_CALLBACK (print_pager_error_cb),
+ data);
+ data->cancel_handler =
+ g_signal_connect (data->pager,
+ "error",
+ G_CALLBACK (print_pager_cancel_cb),
+ data);
+ data->finish_handler =
+ g_signal_connect (data->pager,
+ "finish",
+ G_CALLBACK (print_pager_finish_cb),
+ data);
+
+ /* handled = */ yelp_pager_start (data->pager);
+}
+
+static void
+window_print_page_cb (GtkAction *action, YelpWindow *window)
+{
+ GtkWidget *gtk_win;
+ YelpPager *pager;
+ YelpPage *page = NULL;
+ YelpHtml *html;
+ int length, offset;
+ gchar *uri;
+ GtkWidget *vbox = gtk_vbox_new (FALSE, FALSE);
+
+ gtk_win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ html = yelp_html_new ();
+
+ gtk_container_add (GTK_CONTAINER (gtk_win), GTK_WIDGET (vbox));
+ gtk_box_pack_end (GTK_BOX (vbox), GTK_WIDGET (html), TRUE, TRUE, 0);
+ gtk_widget_show (gtk_win);
+ gtk_widget_show (vbox);
+ gtk_widget_show (GTK_WIDGET (html));
+ gtk_widget_hide (gtk_win);
+
+ pager = yelp_doc_info_get_pager (window->priv->current_doc);
+
+ uri = yelp_doc_info_get_uri (window->priv->current_doc, NULL, YELP_URI_TYPE_FILE);
+
+ yelp_html_set_base_uri (html, uri);
+
+ if (pager) {
+ page = (YelpPage *) yelp_pager_get_page (pager, window->priv->current_frag);
+
+ yelp_html_open_stream (html, "application/xhtml+xml");
+ for (length = strlen (page->contents), offset = 0; length > 0; length -= BUFFER_SIZE, offset += BUFFER_SIZE) {
+ d (g_print ("data: %.*s\n", MIN (length, BUFFER_SIZE), page->contents + offset));
+ yelp_html_write (html, page->contents + offset, MIN (length, BUFFER_SIZE));
+ }
+ yelp_html_close (html);
+ } else { /*html file. Dump file to window the easy way*/
+ GnomeVFSHandle *handle;
+ GnomeVFSResult result;
+ GnomeVFSFileSize n;
+ gchar buffer[BUFFER_SIZE];
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+
+ if (result != GNOME_VFS_OK) {
+ GError *error = NULL;
+ g_set_error (&error, YELP_ERROR, YELP_ERROR_IO,
+ _("The file ā€˜%sā€™ could not be read. This file might "
+ "be missing, or you might not have permissions to "
+ "read it."),
+ uri);
+ window_error (window, error, TRUE);
+ return;
+ }
+ /* Assuming the file exists. If it doesn't how did we get this far?
+ * There are more sinister forces at work...
+ */
+
+ switch (yelp_doc_info_get_type (window->priv->current_doc)) {
+ case YELP_DOC_TYPE_HTML:
+ yelp_html_open_stream (html, "text/html");
+ break;
+ case YELP_DOC_TYPE_XHTML:
+ yelp_html_open_stream (html, "application/xhtml+xml");
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ while ((result = gnome_vfs_read
+ (handle, buffer, BUFFER_SIZE, &n)) == GNOME_VFS_OK) {
+ yelp_html_write (html, buffer, n);
+ }
+
+ yelp_html_close (html);
+
+
+
+ }
+ g_free (uri);
+ yelp_print_run (window, html, gtk_win, vbox);
+}
+
static void
window_about_document_cb (GtkAction *action, YelpWindow *window)
{